问题 单元测试,死锁和竞争条件


关于如何为可能容易出现死锁和竞争条件的代码编写可重复单元测试的任何建议?

现在我倾向于跳过单元测试并专注于压力测试。问题是你可以进行5次压力测试并看到5种不同的结果。

编辑:我知道它可能只是一个梦想,但如果有一种方法来控制单个线程并导致它们一次执行一条指令,那么我可能会到达某个地方。


4140
2017-10-06 23:21


起源

免责声明:我在Typemock工作。 我已经看过关于Typemock Racer的评论,我想澄清一些事情:1。Racer是 不 一个“压力测试工具”,它使用静态和动态分析算法来发现.NET代码中的死锁。这意味着如果没有使用Racer发现死锁,则不存在死锁(除非我们有错误:))。 2.我们正在努力将Race条件发现添加到Racer - 在(近)未来版本中我们将进行竞争条件分析但当前版本仅发现死锁。 3.最后 - Racer处于Alpha阶段,这意味着它可以免费下载和使用b - Dror Helper


答案:


看一眼 TypeMock 赛车手(它在Beta中)

编辑:实际上是Alpha

http://www.typemock.com/Typemock_software_development_tools.html


3
2017-10-06 23:24



叫我持怀疑态度。我已经有了种族条件,即使我弄清楚是什么导致了它们,我也无法复制。 TypeMock Racer可能会找到一些,但它只是一个压力测试。传球并不意味着他们没有任何比赛条件。它仍然可能有用。 - Kevin Gale
这不是真正的“单元测试”,但它可能会有用。 - Jonathan Allen
不,可以阅读IL并告诉您是否有死锁然后让你陷入困境。我刚刚得到了一个演示,但这就是我理解它们的意思,因为他们解释了它。 - Lou Franco
我同意它可能非常有用,但我不认为这是一个单元测试,因为传递意味着你没有死锁或竞争条件。 - Kevin Gale
链接不再有效。 - dzieciou


通常可以强迫 预见 竞争条件和死锁通过使用像ManualResetEvent之类的东西在释放之前让每个线程进入预期状态 - 即获取线程A以获得锁定并等待信号...获取线程B以请求锁定等...

但是 - 您通常可以编写这样的测试来调查可疑的bug,以证明它何时被修复并且不会重新浮出水面。你通常会围绕竞争条件进行设计(但最好是务实地测试它们)。


2
2017-10-06 23:27



注意 - 等待事件会导致缓存刷新,这可能会掩盖竞争条件。在这种情况下延迟使用for循环是值得的。 - finnw
足够公平 - 我正在谈论更多关于证明 后果 僵局,并显示它们固定 - 但点了。 - Marc Gravell♦


我不认为寻找竞争条件真的属于单元测试领域。根据定义,或多或少,测试竞争条件的唯一方法是伪随机的。除非你愿意正式努力证明锁定策略的正确性,否则你将不得不做一些压力测试。

您仍然需要编写单元测试,以验证算法的正确性,而不是锁定策略。

在对多线程代码进行压力测试时,您需要在每个线程有一个CPU的情况下进行测试,其中您有多个线程共享CPU,并且您拥有的CPU数多于线程数(如果可能)。


2
2017-10-06 23:31





您可以通过查看锁定操作的顺序来编写一个检测潜在死锁的锁类。我们通过在获取所有锁定时注册的线程上下文来做到这一点(可以作为DEBUG only选项)。

这个想法是创建一个图形,其中节点代表锁定,A和B之间的有向边缘意味着“获取锁定B时保持锁定A”。让您的程序使用正常负载运行,然后检查图中的周期。一个循环意味着即使你的代码没有命中它也有可能发生死锁。


2
2017-10-06 23:44





想不出一个好的自动化方式,但我最接近的是编写一个“暴露”死锁的单元测试,除了单元测试之外还使用了断点。我只是添加了一些关于添加断点的指令。需要进行一些手动操作,但是对于它们,您可以随时公开更糟糕的案例线程安排。

也许有人想出了一种自动化这种功能的好方法?我可以想象自动运行调试器,在特定行中断开一个线程,让另一个线程运行到特定条件,然后断言单元测试。


1
2017-10-06 23:27



断点的问题在于它改变了代码的行为方式。附加调试器时,不会发生指令重新排序和内联等活动。 - Jonathan Allen


我以前在代码中使用了由请求中的某些参数触发的人为延迟。例如,一个请求告诉服务器延迟两次写入之间的写入,而另一次请求则在两次写入之间没有延迟。

Mark Bessey写道,这只对创建repro有用,而不是用于发现问题。


0
2017-10-20 13:22





你有没有尝试过 Corensic Jinx


0
2017-07-22 21:32