.net – 什么可能导致死锁或以其他方式导致此并发测试不一致失败?

我一直在摆弄
CHESS,这似乎是一个非常有用的工具.然而,具有讽刺意味的是,我似乎在我的一种测试方法中处理了一个Heisenbug.运行此测试时CHESS报告的结果是不可预测的:

>有时测试会通过
>有时候测试会失败,没有进一步的描述(简单地说:“测试失败”)
>有时候测试会失败并附有复制说明*
>有时测试会显示“CHESS检测到死锁”

最初,我认为这种不一致必须是因为测试涉及使用Random对象.一定是不同的种子价值产生了不同的结果,对吧?

所以我更新了测试,只需运行一组预定义的种子值(0到10).线程局部随机对象由锁中的共享随机生成的(伪)随机值接种.代码看起来基本上是这样的:

(更新:我在.NET 3.5上运行它,因为CHESS只支持VS 2008.我想知道这个问题是否与this有关?)

据我了解,上面的代码实际上应该是非常确定的.由于sharedRandom是使用已知种子(0到10之间)初始化的,因此属于运行Parallel.For调用内部代码的每个线程的localRandom对象生成的值应该从一次测试运行到下一次测试运行一致(哪个线程得到哪个)来自sharedRandom的种子在运行之间可能不同,但在Parallel.For中的5次迭代中,相同的5种子应该用于localRandom).

这就是我理解它的方式.但是从CHESS的结果来看,我倾向于相信我必须遗漏一些东西.

>上面的代码中是否存在死锁,我太傻了?
>我应该在并发相关的测试中不使用Random类吗?
>对于有使用CHESS经验的人:它是一个可靠的工具吗?它有时会产生误报吗?这实际上是一个很大的问题,好像事实证明这种情况很常见(测试结果不一致),那么我可能暂时不推迟使用CHESS.

* …我无法弄清楚如何使用 – 但这是一个单独的问题.

最佳答案 没有答案,我会试一试.对我而言,发布的代码片段如何失败并不是很明显,我怀疑真正的问题在于评论.

我没有CHESS的实践经验,但研究得很好,知道你不能依靠它来给你可重复的测试结果.揭示线程问题的方法是非常统计的,在线程中注入随机延迟.旨在重现那种受时间特别严重影响的线程问题.

如果代码执行时间是可预测的,则竞争条件可能在很长时间内未被检测到.当它罢工时,难以诊断.这方面的一个很好的例子是我听说的一个大型政府项目随着日志记录一直开启.因为它关闭它将不再有效,没有记录信息就没有好的方法来诊断问题.

威胁CHESS作为诊断工具.如果它引发了一个标志,你可以相当确定你有一个真实但仍然很难解决的线程问题.

点赞