如何最好地测试Mutex实现?

grr*_*sel 10 c++ testing concurrency automated-tests mutex

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

我想到的最好的是让许多(N)并发线程迭代地尝试访问受保护区域(I)次,这具有副作用(例如更新到全局),以便访问+写入的次数可以是计算以确保全局更新的数量正好是(N)*(I).

还有其他建议吗?

S.L*_*ott 8

正式证明比测试这种东西更好.

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

很难测试硬件中可用的每个操作顺序,以确保您的互斥锁在所有情况下都能正常工作.

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

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

同样,您必须证明该版本是原子的.


Jer*_*fin 7

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


小智 5

我和其他所有人一样,要最终证明这一点非常困难,我不知道该怎么做 - 我知道这没有帮助!

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

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

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

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

祝你好运!


ewe*_*nli 4

这让我想起了这个关于FIFO 信号量测试的问题。简而言之,我的回答是:

  • 即使你有一个规范,也许它并不能准确表达你的意图
  • 您可以证明算法满足规范,但不能证明代码 (D. Knuth)
  • 测试仅揭示错误的存在,而不是不存在(Dijkstra)

所以你的建议似乎是最好的选择。如果您想增加信心,请使用模糊测试来随机化调度和输入。