17

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

4

5 回答 5

16

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

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


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

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

以下问题对此有更多信息: C++ Thread, shared data

于 2008-10-21T18:25:42.210 回答
7

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

于 2008-10-21T18:26:12.847 回答
4

As for C++11 and later it is finally threads-aware and clearly states that modifying a bool (or other non-atomic variable) in one thread and accessing it at the same time in another one is undefined behavior. In you case using std::atomic<bool> should be enough to make your program correct, saving you from using locks.
Do not use volatile. It has nothing to do with threads. For more discussion look at Can I read a bool variable in a thread without mutex?

于 2017-12-18T13:40:17.650 回答
3

我认为您在这里不需要一个完全成熟的互斥锁——尽管如果您不使用支持等待原语的同步对象,渲染线程将需要在“暂停”状态下忙于等待。

您应该考虑使用各种互锁交换原语(Windows 下的 InterlockedExchange)。不是因为来自布尔的读/写是非原子的,而是为了确保没有奇怪的行为,编译器在单个线程上重新排序内存访问。

于 2008-10-21T18:27:16.947 回答
1

这个线程有更多关于线程安全的信息和讨论,特别是对于简单的数据类型:

How can I create a thread-safe singleton pattern in Windows?

于 2008-10-21T18:35:20.193 回答