在多线程C++应用程序中,我是否需要一个互斥锁来保护一个简单的布尔值?

Bri*_*art 14 c++ multithreading mutex boolean openscenegraph

我有一个多线程C++应用程序,它使用OpenSceneGraph库进行3D渲染.我打算使用boost :: threads将OSG的渲染循环作为一个单独的线程,将包含共享状态的数据结构传递给线程.我试图避免任何太重量级(如互斥量)的同步,因为渲染循环需要非常紧,OSG本身试图避免必须锁定.大多数共享状态在线程启动之前设置,并且从不更改.我确实有一些需要更改的数据,我计划双重缓冲.但是,我有一个简单的布尔值来表示线程暂停渲染,然后恢复渲染,另一个杀死它.在这两种情况下,app线程都会设置bool,而渲染线程只会读取它.我是否需要同步访问这些bool?据我所知,可能发生的最糟糕的事情是渲染循环在暂停或退出之前继续进行额外的帧.

Gre*_*ill 15

在C++ 11及更高版本中,它具有标准定义的并发性,std::atomic<bool>用于此目的.来自http://en.cppreference.com/w/cpp/atomic/atomic:

如果一个线程写入原子对象而另一个线程从中读取,则行为是明确定义的(有关数据争用的详细信息,请参阅内存模型).


在过去的某些时候,对于某些编译器和某些操作环境,以下旧答案可能都是正确的,但今天不应该依赖它:

你没错,在这种情况下你不需要同步bool.你应该声明它们volatile,以确保编译器每次实际从内存中读取它们,而不是在线程中缓存先前的读取(这是一个简化的解释,但它应该为此目的).

以下问题提供了有关此内容的更多信息: C++线程,共享数据

  • volatile不会阻止读/写重新排序.VC++ 2005/8似乎通过以与Java 5相同的方式为关键字volatile添加其他含义来正确地执行此操作.另一方面,海湾合作委员会肯定会重新订购东西. (6认同)
  • 这是真的但没有用.必须已经评估了对volatile对象的访问,但C++没有说明来自另一个线程的写是否对您的线程可见,因为C++对线程没什么好说的.您必须查阅编译器/线程文档,或使用C++ 0x. (5认同)
  • 然而,这并不是规范实际上做的"不稳定".MSVC对懒惰的程序员有点宽容,但是GCC肯定会愉快地优化,重新安排和破坏你的"易变"内存访问. (2认同)

sho*_*osh 7

为什么不简单地使用互锁变量