在多线程 C++ app,我需要一个互斥体来保护一个简单的布尔值吗?

发布于 2024-07-08 16:44:01 字数 371 浏览 12 评论 0原文

我有一个多线程 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.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(5

≈。彩虹 2024-07-15 16:44:01

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

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


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

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

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

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:

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).

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

浪推晚风 2024-07-15 16:44:01

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

Why not simply use an interlocked variable?

¢蛋碎的人ぎ生 2024-07-15 16:44:01

至于 C++11 及更高版本,它最终是线程感知的,并明确指出在一个线程中修改 bool (或其他非原子变量)并同时在另一个线程中访问它是未定义的行为。
在您的情况下,使用 std::atomic 应该足以使您的程序正确,从而避免使用锁。
不要使用易失性。 它与线程无关。
有关更多讨论,请参阅我可以读取布尔值吗线程中的变量没有互斥锁?

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?

烂柯人 2024-07-15 16:44:01

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

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

I don't think you need a fully fledged mutex here -- though the render thread will need to busy wait in the 'suspended' state if you aren't using a synchronization object that supports a wait primitive.

You should look into using the various interlocked exchange primitives though (InterlockedExchange under Windows). Not because read/writes from the bool are non-atomic, but to ensure that there are no weird behaviours the compiler reordering memory accesses on a single thread.

残月升风 2024-07-15 16:44:01

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

如何在 Windows 中创建线程安全的单例模式?

This thread has a little more info and discussion on thread-safety, especially for simple data types:

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

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文