- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
问题如何确保我的应用程序是线程安全的?他们是否有任何常规做法,测试方法,要避免的事情,要寻找的事情?
背景我当前正在开发一个服务器应用程序,该应用程序在不同的线程中执行许多后台任务,并使用Indy(使用另一组自动生成的线程进行通信)与客户端进行通信。由于该应用程序应该具有很高的可用性,因此程序崩溃是一件非常糟糕的事情,我想确保该应用程序是线程安全的。无论如何,有时我会发现一段代码抛出从未发生过的异常,并且在大多数情况下,我意识到这是某种同步错误,我忘记了正确同步对象。因此,我的问题涉及最佳实践,线程安全性测试以及类似的问题。
mghie:感谢您的回答!我也许应该更精确一些。明确地说,我了解多线程的原理,在整个程序中使用同步(监视器),并且知道如何将线程问题与其他实现问题区分开。但是,尽管如此,我仍然忘记不时添加适当的同步。仅举一个例子,我在代码中使用了RTL排序功能。看起来像
FKeyList.Sort (CompareKeysFunc);
最佳答案
您不能真正测试线程安全性。您所能做的就是证明您的代码不是线程安全的,但是如果您知道该怎么做,那么您已经知道该如何在程序中修复该特定的错误。问题是您不知道的错误,您将如何编写这些错误的测试?除此之外,线程问题比其他问题更难发现,因为调试行为已经可以改变程序的行为。从一个程序运行到下一个程序,从一台机器运行到另一台机器,事情将有所不同。 CPU和CPU内核的数量,并行运行的程序的数量和种类,程序中发生的事情的确切顺序和时间-所有这些以及更多这些都会影响程序的行为。 [我实际上想将月相和类似的东西添加到此列表中,但是您明白了我的意思。]
我的建议是停止将其视为实现问题,而开始将其视为程序设计问题。无论是否为Delphi编写,都需要学习并阅读所有有关多线程的知识。最后,您需要了解基本原理,并在编程中正确应用它们。操作系统提供了诸如关键部分,互斥,条件和线程之类的基元,并且大多数语言仅将它们包装在它们的库中(这忽略了诸如Erlang等提供的绿色线程之类的东西,但这是一个很好的出发点)。
我想说的是从Wikipedia article on threads开始,然后逐步完成链接的文章。我从亚伦·科恩(Aaron Cohen)和迈克·伍德林(Mike Woodring)的"Win32 Multithreaded Programming"书开始-已经绝版,但也许您可以找到类似的书。
编辑:让我简短地跟进您已编辑的问题。所有对非只读数据的访问都必须正确同步以确保线程安全,并且对列表进行排序不是只读操作。因此很明显,需要在列表的所有访问周围添加同步。
但是随着系统中内核越来越多,常量锁定将限制可以完成的工作量,因此,寻找一种不同的方法来设计程序是一个好主意。一种想法是在程序中引入尽可能多的只读数据-不再需要锁定,因为所有访问都是只读的。
我发现接口(interface)对于设计多线程程序非常有用。可以将接口(interface)实现为仅具有对内部数据进行只读访问的方法,并且如果您坚持使用这些接口(interface),则可以确定不会发生很多潜在的编程错误。您可以在线程之间自由共享它们,并且线程安全的引用计数将确保在最后一个对它们的引用超出范围或分配了另一个值时,可以正确释放实现对象。
您要做的是创建从TInterfacedObject继承的对象。它们实现一个或多个接口(interface),这些接口(interface)全部仅提供对对象内部的只读访问,但是它们也可以提供使对象状态发生变化的公共(public)方法。创建对象时,请同时保留对象类型的变量和接口(interface)指针变量。这样,生命周期管理很容易,因为在发生异常时将自动删除对象。您使用指向该对象的变量来调用正确设置该对象所需的所有方法。这会改变内部状态,但是由于这种情况仅发生在 Activity 线程中,因此没有潜在的冲突。一旦正确设置了对象,您就可以将接口(interface)指针返回到调用代码,并且由于以后无法访问该对象,因此除非通过接口(interface)指针,否则您可以确保只能执行只读访问。通过使用此技术,您可以完全消除对象内部的锁定。
如果需要更改对象的状态怎么办?不需要,您可以通过从接口(interface)复制数据来创建一个新对象,然后再更改新对象的内部状态。最后,将引用指针返回到新对象。
通过使用此功能,您仅需要锁定获取或设置此类接口(interface)的位置。通过使用原子交换功能,甚至可以在不锁定的情况下完成此操作。有关设置接口(interface)指针的类似用例,请参见Primoz Gabrijelcic的this blog post。
关于multithreading - 实现线程安全,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/564319/
我有2个功能: function func1() while true do -- listen on connection end end function func2()
我的问题可能看起来很奇怪,但我想我正面临着 volatile 的问题。对象。 我写了一个这样实现的库(只是一个方案,不是真正的内容): (def var1 (volatile! nil)) (def
由于 maven 支持多线程构建,是否可以同时运行 Sonar 多线程? (例如 mvn sonar:sonar -T 4 ) 我运行了它,当模块报告成功时,它报告整个构建失败并返回 java.uti
我们正在启动一个网站,该网站在短时间内的交易量非常大。它基本上是在给票。该代码是用Java,Spring和Hibernate编写的。我想通过产生多个线程并尝试使用JUnit测试用例来获取票证来模仿高容
我正在尝试访问像素数据并将图像从游戏中的相机保存到磁盘。最初,简单的方法是使用渲染目标,然后使用RenderTarget-> ReadPixels(),但是由于ReadPixels()的 native
我们有以下系统: 用户数:〜500k 项目数:〜100k UserSimilarity userSimilarity = new TanimotoCoefficientSimilarity(dataM
也许这是一个经常出现的问题,但我需要根据我的上下文进行一些自定义。 我正在使用 Spring Batch 3.0.1.RELEASE 我有一个简单的工作,有一些步骤。一个步骤是这样的 block :
也许这是一个经常出现的问题,但我需要根据我的上下文进行一些自定义。 我正在使用 Spring Batch 3.0.1.RELEASE 我有一个简单的工作,有一些步骤。一个步骤是这样的 block :
我正在尝试使用PyBrain和Python的multiprocessing软件包在Python中训练神经网络。 这是我的代码(它训练了一个简单的神经网络来学习XOR逻辑)。 import pybrai
我有一个繁重的功能,不适合在主时间轴上执行(因为要花很长时间才能完成并使程序崩溃)。 因此我在air(as3)中搜索多线程,但是我发现的所有示例都说明了如何在worker中运行单独的swf文件。如何在
我想实现线程A 和线程B 并行运行并共享全局变量。 下面是用python编写的代码。我想在中执行相同操作Dart (我不想使用future等待,因为它正在等待其他线程完成或必须等待。) 大小写变量:
我的一个项目只适用于调试 DLL,而不适用于非调试 DLL。 在 Debug DLL 设置下发布项目有哪些注意事项?例如,是否丢失了某些优化? 如何通过将调试版本设置为非调试 DLL 来调试此项目?我
我正在尝试比较 Matlab 和 Julia 之间的速度和性能。我正在查看一个代码,该代码对承受给定负载的连续体结构进行拓扑优化。我正在查看的代码是公共(public)代码topopt88.m:htt
Serving Flask 应用程序“服务器”(延迟加载) 环境:生产警告:这是一个开发服务器。不要在生产部署中使用它。请改用生产 WSGI 服务器。 Debug模式:开启 在 http://0.0.
我对 PyQT 很陌生。我正在学习如何制作 Progressbar 并随着算法的进展对其进行更新。我已经能够制作一个使用此链接进行 self 更新的基本进度条:Python pyqt pulsing
我正在尝试指定在特定线程上运行任务,这样我就可以使用两个专用于“放入” channel 的耗时任务的线程,而其他线程则用于处理该任务。 我对如何将特定任务分配给特定线程感到困惑。我以为我可以使用类似
我正在编写一个软件,它对很多(潜在的大)图像进行大量图像操作/合成。 多线程有助于提高速度,但 QT 不允许同时在同一图像上使用多个 QPainter。 所以我必须在副本的每个线程中进行图像操作/合成
此脚本读取 url 文件以执行多线程 HTTP 请求。 如何使用带有 url 的数组来发出多线程请求? 我的阵列将有类似的东西: @array = ("https://example.com/xsd"
Java 文档声明了以下关于构造函数同步的内容: Note that constructors cannot be synchronized — using the synchronized keyw
我有一个程序,其中主线程创建了很多线程。它崩溃了,我正在调试核心文件。崩溃发生在其中一个子线程中。为了找到原因,我需要知道主线程是否还活着。有什么方法可以找出哪个线程是初始线程? 最佳答案 Is th
我是一名优秀的程序员,十分优秀!