2010-03-04 63 views
10

测试互斥锁实现的最佳方法的确是正确的? (有必要实现一个互斥锁,重用不是一个可行的选择)如何最好地测试Mutex实现?

我已经想出了最好的是有很多(N)并发线程迭代试图访问受保护区域(I)次,它已一个副作用(例如更新到全局),以便可以统计访问次数和写入次数,以确保全局更新的数量正好是(N)*(I)。

其他建议?

+1

测试互斥锁(以及类似的构造)非常非常困难。我很想知道为什么你不能使用预先存在的,经过测试和证明的解决方案。 – 2010-03-04 16:30:33

+0

“因为我的老板告诉我” – 2010-03-04 16:35:23

回答

3

这让我想起这个关于FIFO semaphore test的问题。简单地说我的回答是:

  • 即使你有一个规范,也许它没有传达你的意图究竟
  • 可以证明,该算法符合规范,而不是代码(D.高德纳)
  • 测试只揭示了错误的存在,而不是他们的缺席(Dijkstra算法)

所以,你的主张似乎合理的最好的事情。如果您想提高信心,请使用模糊随机化调度和输入。

8

形式证明比测试这种事情要好。

测试会告诉你 - 只要你不是不吉利的 - 一切都会奏效。但是一个测试是一个钝器,它可能无法执行正确的顺序以导致失败。

要测试硬件中可用的每一个可能的操作顺序,以确保您的互斥锁在任何情况下都能正常工作,这太困难了。

测试并非没有价值;它表明你没有犯任何明显的编码错误。

但是您确实需要更正式的代码检查来证明它在正确的时间执行了正确的事情,以便一个客户端可以自动获取正确的互斥锁所需的锁资源。在许多平台中,有特别的指示来实现这一点,如果你使用其中的一种,你有一个正确的战斗机会。

同样,你必须证明该版本是原子的。

7

有了像互斥体这样的东西,我们回到了旧规则,即测试只能证明错误的存在,而不是缺失。一年的测试可能会告诉你不仅仅是将代码放在检查中,并询问是否有人看到问题。

1

如果证明的东西不适合你,那么去测试一个。一定要测试所有可能的用例。了解如何使用这个东西,谁将使用它,以及如何使用它。当你走上测试路线时,一定要对每个场景进行每次测试(数百万,数十亿,尽可能多的测试时间)。

尝试随机,因为随机性会给你最好的机会覆盖有限数量测试中的所有场景。请务必使用将要使用的数据和可能未使用但可以使用的数据,并确保数据不会混淆锁定。

顺便说一句,除非你知道数学和形式方法很多,否则你将没有机会真正提出证明。

4

我与其他人一样,这是难以置信的难以证实的决定性的,我不知道该怎么做 - 没有帮助,我知道!

当您说实现一个互斥锁并且重用不是一个选项时,是出于技术原因,例如您正在使用的平台/操作系统上没有Mutex实现或其他原因?正在封装某种形式的操作系统级别的“锁定”并将其称为您的互斥体实现选项,例如,关于windoze的criticalsection,posix条件变量?如果你可以封装一个较低级别的操作系统锁,那么你获得正确的机会要高得多。

如果您还没有这样做,请阅读Herb Sutter's Effective Concurrency文章。这些东西应该有些值得你去做。

无论如何,有些事情在你的测试考虑:

  • 如果你的互斥是递归的(即可以在同一线程锁定多个 次),然后确保你做一些 引用计数测试。
  • 随着你的全局变量,你 修改它将是最好的,如果这是一个 变量,不能被写入 原子。例如,如果您在8位平台上为 ,则使用16位或 32位变量,需要使用多个汇编指令来编写。
  • 仔细检查装配清单。取决于硬件平台,虽然程序集并不直接转化为代码可能被优化的方式......
  • 让别人写不出代码,也写一些测试。
  • 测试作为许多不同的机器有不同的规格,你可以(假设这是“通用”,而不是针对特定的硬件设置)

祝你好运!

+0

关于正在写入的值的大小的好处。我的主要问题是检查使用的处理器操作(通过编译器内在函数访问)的组合在理论上和逻辑上都是正确的(在算法上是正确的)并且实际上是正确的(实现编译忠实于逻辑正确的算法) – grrussel 2010-03-05 15:08:06

相关问题