使用“常规”变量来同步线程

时间:2013-04-09 21:08:34

标签: c++ multithreading synchronization

如果我只有两个线程,并且我希望其中一个线程等待另一个线程达到某个点,那么执行以下操作是否安全:

bool wait = true;

//Thread 1:
while(wait) ;
wait = true; //re-arm the signal

//Thread 2:
/* Preform here the code that needs to complete before Thread 1 continues */
wait = false;

基本上,如果一个线程只写入它而另一个只读取,那么会出现问题吗?我假设单个bool的读取或写入是原子的,即使不是,我也看不出它如何在这里产生影响。

2 个答案:

答案 0 :(得分:5)

不,它无法运作。如果您使用std::atomic<bool>,它将起作用。

C ++中的Atomics解决了三个问题。首先,在存储或读取需要多个总线周期的值的过程中发生线程切换的可能性;这被称为“撕裂”。第二,两个线程将在具有两个独立缓存的两个独立处理器上运行的可能性,并且一个线程将看不到另一个线程所做的更改。这称为“缓存一致性”。第三,编译器可能会移动代码,因为顺序看起来并不重要。

即使bool值可能只需要一个总线周期来读取或写入,但它不能解决其他两个问题。

没有可靠的捷径。使用适当的同步。

答案 1 :(得分:0)

虽然您会获得std::atomic<bool>的保证,但我认为您可以使用简单的volatile,因为:

  • 编译器无法对volatile
  • 上的指令重新排序
  • 其中一个线程总是写入变量,因此指令实际上是原子的
  • 另一个线程不需要执行read和write atomically

所以不会有任何形式的撕裂。但是,缓存一致性的问题仍然存在,而且依赖于硬件或操作系统。