【问题标题】:How to write tests that check for race conditions?如何编写检查竞争条件的测试?
【发布时间】:2013-09-12 18:18:00
【问题描述】:

我目前正在从事一个大型项目,该项目最近发生了许多变化,最突出的是添加了线程支持。

在查看代码时,我已经确定了可能导致竞态条件的部分,如果不是现在,那么在将来的某个时间。为了防止这种回归,我想编写一个测试,可以可靠地检测该特定区域中的竞争条件,以确保未来的提交不会导致此错误。
代码中没有乱七八糟的 sleep() 语句,而是一个潜在的死锁和竞争雷区,我想确保健壮性。

这个项目完全是用 C 语言编写的。那么,我是否可以编写单元测试来防止出现竞争条件?

【问题讨论】:

  • 这很难做到,并且很大程度上取决于具体的应用程序细节。通过直接行动导致比赛条件失败也是非常困难的,而且通常是不可能的。

标签: c multithreading concurrency race-condition


【解决方案1】:

竞争条件本质上是非确定性的结果。如果您不能确保调用序列是安全的,那么引入一些运行时检查来验证协议不变量是否得到遵守。然后,至少无论何时发生故障,您都会有证据。

虽然这不能解决您的问题,但它至少为您提供了一个量化问题程度的工具。

如果任何竞赛是由应用程序范围之外的事件触发的,那么任何静态分析都需要对其进行建模以便能够检测条件。

【讨论】:

    【解决方案2】:

    Valgrind DRD 工具可用于检测许多线程错误。只需使用此工具并运行您常用的测试用例即可。

    【讨论】:

      【解决方案3】:

      Clang Thread Sanitizer 的工作原理是在执行时观察您的测试过程。每当一个线程在不受保护的情况下读取或写入内存时,它都会记录下来,并且它会告诉您是否有任何一块内存被多个线程不受保护地访问。

      【讨论】:

      • 我已经在 GCC 上使用了线程清理器。问题不仅仅是检测竞争条件,而是确定性地重现它们。
      • 我相信你不能对程序的竞争条件进行单元测试。您可以做的是编写 unittest 来重现通过其他方式发现的竞争条件,并使用它来确保您已经消除了它。但是您必须首先从已知的竞争条件开始,您无法以这种方式发现它们。在 Java 中,有 Byteman (JBoss) 或 Thread Weaver (Google)。在 C 语言中,我要么总是使用 nanosleeps(在正确的地方睡觉会大大增加发生竞争的机会),要么我添加了同步/条件变量以确保我让所有线程都在我想要重现的同一个活泼操作上。
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2016-07-22
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2019-03-20
      • 1970-01-01
      相关资源
      最近更新 更多