【问题标题】:How best to test a Mutex implementation?如何最好地测试 Mutex 实现?
【发布时间】:2010-03-04 16:24:22
【问题描述】:

测试互斥锁实现是否正确的最佳方法是什么? (必须实现互斥锁,重用不是可行的选择)

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

还有其他建议吗?

【问题讨论】:

  • 测试互斥体(和类似的结构)非常非常困难。我很想知道为什么您不能使用预先存在、经过测试和证明的解决方案。

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


【解决方案1】:

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

测试会告诉你——只要你不走运——一切都会奏效。但是测试是一种钝器;它可能无法执行正确的顺序而导致失败。

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

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

但是您确实需要更正式的代码检查来证明它在正确的时间做正确的事情,以便客户端自动获取正确互斥锁所需的锁资源。在许多平台中,都有特殊的说明来实现这一点,如果您使用其中的一种,那么您就有很大的机会把它做好。

同样,你必须证明发布是原子的。

【讨论】:

    【解决方案2】:

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

    【讨论】:

      【解决方案3】:

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

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

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

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

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

      祝你好运!

      【讨论】:

      • 关于正在写入的值的大小的要点。我的主要问题是检查所使用的处理器操作组合(通过编译器内在函数访问)在理论上和逻辑上是否正确(在算法上是否正确)和实际上是否正确(编译的实现是否忠实于逻辑上正确的算法)
      【解决方案4】:

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

      • 即使您有规范,也可能无法准确传达您的意图
      • 您可以证明算法符合规范,但不能证明代码 (D. Knuth)
      • 测试只显示错误的存在,而不是它们的缺失 (Dijkstra)

      因此,您的提议似乎是最好的做法。如果您想增加信心,请使用 fuzzing 来随机化调度和输入。

      【讨论】:

        【解决方案5】:

        如果证明内容不适合您,请继续进行测试。请务必测试所有可能的用例。找出这个东西将如何使用,谁将使用它,以及如何使用它。当您走测试路线时,请确保为每个场景运行大量测试(数百万、数十亿,尽可能多地使用您拥有的测试时间)。

        尽量做到随机,因为随机性会让您有最好的机会在有限数量的测试中涵盖所有场景。一定要使用将要使用的数据和可能不会使用但可以使用的数据,并确保数据不会弄乱锁。

        顺便说一句,除非您对数学和形式化方法有很多了解,否则您将没有机会真正提出证明。

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 2012-03-29
          • 1970-01-01
          • 1970-01-01
          • 2012-11-19
          • 2020-09-23
          • 2019-12-05
          • 1970-01-01
          相关资源
          最近更新 更多