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

时间:2008-10-06 23:21:03

标签: c# .net vb.net parallel-processing

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

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

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

7 个答案:

答案 0 :(得分:3)

看一下TypeMock Racer(它是Beta版)

编辑:实际上是Alpha

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

答案 1 :(得分:2)

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

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

答案 2 :(得分:2)

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

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

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

答案 3 :(得分:2)

通过查看锁定操作的顺序,您可以编写一个检测潜在死锁的锁类。我们通过创建一个线程上下文来执行此操作,所有线程上下文在获取时都会注册(可以作为DEBUG only选项)。

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

答案 4 :(得分:1)

无法想到一个好的自动化方式,但我最接近的是编写一个单独的测试,通过在单元测试之外使用断点来“揭露”死锁。我只是添加了一些关于添加断点的说明。需要进行一些手动操作,但有了它们,您可以随时公开更糟糕的案例线程安排。

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

答案 5 :(得分:0)

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

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

答案 6 :(得分:0)

您是否尝试过Corensic Jinx