Possible Duplicate:
When to use volatile with multi threading?
我有两个线程引用相同的boost::shared_ptr
:
boost::shared_ptr<Widget> shared;
On 线程正在旋转,等待另一个线程重置 boost::shared_ptr
:
while(shared)
boost::thread::yield();
在某个时刻另一个线程会调用:
shared.reset();
我的问题是我是否需要将共享指针声明为 volatile
以防止编译器优化对 shared.operator bool()
的调用循环并且从不检测变化?我知道如果我只是在一个变量上循环,等待它达到 0,我将需要 volatile
,但我不确定是否实现了 boost::shared_ptr
以这种方式在这里没有必要。
编辑:我完全知道条件变量可以用来以不同的方式解决这个问题。但在这种情况下,繁忙的循环非常少见,并且争用条件变量上的锁是一种我们不愿承担的开销。
咆哮1:
该代码可能不会按照您的预期执行。当您编写这样的代码时,您将引入一个 data race进入你的代码。 这几乎可以肯定是一个错误,它将导致您的程序 non-deterministically failing .
数据结构(包括 shared_ptr)通常不应该被并发访问。不要在多个线程中同时修改同一个结构。这可能会破坏结构。不要在一个线程中修改它并在另一个线程中读取它。读者可能会看到不一致的数据。 可能多个线程可以同时读取它。
如果您认为自己确实想要执行上述某些操作,请在可能标题为“线程安全”的部分中查明数据结构是否允许其中的某些行为。如果确实允许,请再看看您的性能是否真的需要它,然后再使用它。 (shared_ptr 上的文档不允许您在做什么。)
咆哮2:
现在,对于更高级别的问题,您可能不应该通过等待指针设置为 NULL 来进行线程同步。实际上,将条件变量、障碍或 future 视为一种让一个线程等待另一个线程完成某事的方法。这是一个更好的界面,接下来(包括 6 个月内的你)看到你的代码的人都会感谢你。
我知道您担心真正同步的性能成本。别担心这个。会没事的。如果您担心锁争用,请使用 barrier 或 futures,它们没有可争用的大共享锁。
警告:有时要编写不惜一切代价避免锁定的代码。但除非您查看的分析器数据表明您的同步操作对于您的目标工作负载而言太慢,否则现在不是时候。
咆哮3:
我希望您示例中的 shared
是全局的。否则,您将有多个线程对指向您感兴趣的真实对象的同一 shared_ptr
进行本地引用。这有点违背了拥有引用计数指针的目的。请告诉我它是全局性的。