如何最好地测试Mutex实现?

时间:2010-03-04 16:24:23

标签: c++ testing concurrency automated-tests mutex

测试互斥锁实现的最佳方法是什么? (有必要实现互斥,重用不是一个可行的选择)

我提出的最好的方法是让许多(N)并发线程迭代地尝试访问受保护区域(I)次,这会产生副作用(例如更新为全局),以便访问次数+可以计算写入以确保全局更新的数量正好是(N)*(I)。

还有其他建议吗?

5 个答案:

答案 0 :(得分:8)

正式证明比测试此类事物要好。

测试会告诉你 - 只要你不是不走运 - 这一切都有效。但是测试是一种钝器;它可能无法执行完全正确的序列以导致失败。

要测试硬件中可用的所有可用操作序列以确保您的互斥锁在所有情况下都能正常工作,这太难了。

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

但是你真的需要一个更正式的代码检查来证明它在正确的时间做了正确的事情,这样一个客户端就会原子地抓住正确的互斥锁所需的锁资源。在许多平台上,有一些特殊的指令可以实现这一点,如果您正在使用其中一个,那么您就有机会做到这一点。

同样,你必须证明释放是原子的。

答案 1 :(得分:7)

使用类似互斥锁的东西,我们回到旧的规则,测试只能证明存在错误,而不是缺席。一年的测试可能会告诉你不仅仅是简单地将代码用于检查,并询问是否有人发现它有问题。

答案 2 :(得分:4)

我和其他所有人一起认为这非常难以最终证明,我不知道该怎么做 - 我知道没有帮助!

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

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

无论如何,在你的测试中需要考虑的一些事情:

  • 如果您的互斥锁是递归的(即同一个线程可以将其锁定多次 时间)然后确保你做一些 参考计数测试。
  • 用你的全局变量 修改它最好是这是一个 无法写入的变量 原子。例如,如果你是 在8位平台上然后使用16或 需要的32位变量 要编写的多个汇编指令。
  • 仔细检查装配清单。取决于硬件平台,虽然程序集不会直接转换为代码的优化方式......
  • 让没有编写代码的其他人也写一些测试。
  • 尽可能多地测试具有不同规格的不同机器(假设这是'通用'而非特定硬件设置)
祝你好运!

答案 3 :(得分:3)

这让我想起了关于FIFO semaphore test的这个问题。简而言之,我的回答是:

  • 即使你有一个规范,也许它没有完全表达你的意图
  • 您可以证明算法符合规范,但不符合代码(D. Knuth)
  • 测试只揭示了bug的存在,而不是他们的缺席(Dijkstra)

所以你的命题似乎是最好的。如果您想增加信心,请使用 fuzzing 随机化计划和输入。

答案 4 :(得分:1)

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

尝试随机,因为随机性将为您提供在有限数量的测试中涵盖所有场景的最佳机会。请务必使用将要使用的数据和可能未使用但可以使用的数据,并确保数据不会弄乱锁。

顺便说一下,除非你对数学和形式方法了解不多,否则你将无法提出证据。