【问题标题】:Avoiding data race of boolean variables with pthreads使用 pthread 避免布尔变量的数据竞争
【发布时间】:2014-02-24 08:59:14
【问题描述】:

在我的代码中,我有以下结构:

父线程

somedatatype thread1_continue, thread2_continue; // Does bool guarantee no data race?

线程 1:

while (thread1_continue) {
  // Do some work
}

线程 2:

while (thread2_continue) {
  // Do some work
}

所以我想知道哪种数据类型应该是 thread1_continue 或 thread2_continue 以避免数据竞争。如果 pthread 中有任何数据类型或技术可以解决这个问题。

【问题讨论】:

  • std::atomic<bool> 使用 C++11。
  • std::atomic<bool> 怎么样?

标签: c++ multithreading parallel-processing synchronization pthreads


【解决方案1】:

没有内置的基本 type 可以保证线程安全,无论线程多小。即使您正在使用bool 或unsigned char,也不能保证读取和写入都是原子的。换句话说:如果更多线程独立地使用相同的内存,则一个线程可能仅部分覆盖该内存,而另一个线程读取垃圾值〜在这种情况下,行为未定义 .

您可以使用mutex 用lock 和unlock 调用来包装临界区,以确保互斥 - 只有 1 个线程能够执行该代码。对于更复杂的同步,有信号量、条件变量甚至描述如何使用这些(电灯开关、turniket 等)。多研究这些,一些简单的例子可以找到here :)

请注意,可能有一些更复杂的类型/包装器可以包装对象被访问的方式 - 例如 C++11 中的 std::atomic 模板,它什么都不做,只是在内部为您处理同步,以便您不需要明确地这样做。使用std::atomic 可以保证:“如果一个线程写入原子对象,而另一个线程从它读取,则行为是明确定义的”。

【讨论】:

    【解决方案2】:

    对于布尔值(和其他),请务必避免

    thread 1 loop
    {
      do actions1;
      myFlag = true;
      do more1;
    }
    
    thread 2 loop
    {
      do actions2;
      if (myFlag)
      {
        myFlag = false;
        do flagged actions;
      }
      do more2;
    }
    

    这几乎总是有效,直到 myBool 由 thread1 设置,而 thread2 处于检查和重置 myBool 之间。有一些依赖于 CPU 的原语来处理测试和设置,但正常的解决方案是在访问共享资源时锁定,甚至是布尔值。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2017-12-02
      • 2019-01-10
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2015-01-30
      相关资源
      最近更新 更多