我一直在摆弄CHESS,这似乎是一个非常有用的工具。然而,具有讽刺意味的是,我似乎在我的一种测试方法中处理了一个Heisenbug。运行此测试时CHESS报告的结果是不可预测的:
最初,我认为这种不一致必定是因为测试涉及使用Random
个对象。一定是不同的种子价值产生了不同的结果,对吗?
所以我更新了测试以简单地运行一组预定义的种子值(0到10)。线程局部Random
对象由锁中的共享Random
生成的(伪)随机值播种。代码看起来基本上 完全,如下所示:
(更新:我在.NET 3.5上运行此功能,因为CHESS仅支持VS 2008.我想知道问题是否与this有关?)
据我所知,上面的代码实际上应该是非常确定的。由于使用已知种子(0到10之间)初始化sharedRandom
,因此属于运行localRandom
调用内的代码的每个线程的Parallel.For
对象生成的值应该是一致的测试运行到下一个(哪个线程获取来自sharedRandom
的哪个种子在运行之间可能不同,但在Parallel.For
内的5个迭代中,相同的5个种子应该用于localRandom
)。< / p>
这就是我了解它的方式。但是根据CHESS的结果,我倾向于相信我必须遗漏一些东西。
Random
类?* ...我无法弄清楚如何使用 - 但这是一个单独的问题。
答案 0 :(得分:1)
没有答案,我会试一试。对我而言,发布的代码片段如何失败并不明显,我怀疑真正的问题出现在评论中。
我没有CHESS的实践经验,但研究得很好,知道你不能依赖它来给你可重复的测试结果。揭示线程问题的方法是非常统计的,在线程中注入随机延迟。旨在重现那些受时间特别严重影响的线程问题,特别是竞争条件。
如果代码执行时间可预测,竞争条件很长时间都不会被检测到。当它罢工时,难以诊断。这方面的一个很好的例子是我听说的一个大型政府项目随着日志记录一直开启。因为关闭它将不再有效,没有记录信息就没有好的方法来诊断问题。
威胁CHESS作为诊断工具。如果它引发了一个标志,你可以相当确定你有一个真实但仍然很难解决的线程问题。
答案 1 :(得分:1)
我当然没有看到僵局。 Random可能有内部锁定,但这应该没问题。
您可能想尝试一下Jinx(www.corensic.com)。 Jinx不是生成报告,而是改变各种CPU的有效性能。所以它不能真正产生误报。
如果微小的样本在Jinx下死机,那么它在正常使用期间肯定能够解锁。假设它确实死锁,你应该能够使用Visual studio进入死锁并查看线程的位置。
声明。我为corensic工作。而且我认为你发布的小片段并没有真正的僵局。但我很好奇,所以让我们知道你发现了什么。