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

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

I have a multi-threaded C++ app which does 3D rendering with the OpenSceneGraph library. I'm planning to kick off OSG's render loop as a separate thread using boost::threads, passing a data structure containing shared state in to the thread. I'm trying to avoid anything too heavyweight (like mutexes) for synchronization, as the render loop needs to be pretty tight, and OSG itself tries to avoid having to ever lock. Most of the shared state is set before the thread is started, and never changed. I do have some data that does need to be changed, which I am planning to double-buffer. However, I have a simple boolean for signaling the thread to suspend rendering, and later resume rendering, and another to kill it. In both cases the app thread sets the bool, and the render thread only reads it. Do I need to synchronize access to these bools? As far as I can tell, the worse thing that could happen is the the render loop continues on for an extra frame before suspending or quitting.

推荐答案

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

In C++11 and later, which has standards-defined concurrency, use std::atomic<bool> for this purpose. From http://en.cppreference.com/w/cpp/atomic/atomic:

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

If one thread writes to an atomic object while another thread reads from it, the behavior is well-defined (see memory model for details on data races).

<小时>

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


The following old answer may have been true at some time in the past with some compilers and some operating environments, but it should not be relied upon today:

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

You're right, in this case you won't need to synchronise the bools. You should declare them volatile though, to ensure that the compiler actually reads them from memory each time, instead of caching the previous read in a thread (that's a simplified explanation, but it should do for this purpose).

以下问题有更多相关信息:C++ 线程,共享数据

The following question has more information about this: C++ Thread, shared data

相关文章