可能的重复:
何时在多线程中使用 易失性?
我有两个线程引用相同的内容boost::shared_ptr
:
boost::shared_ptr<Widget> shared;
线程正在旋转,等待另一个线程重置boost::shared_ptr
:
while(shared)
boost::thread::yield();
在某个时刻,另一个线程会调用:
shared.reset();
我的问题是我是否需要将共享指针声明为volatile
防止编译器优化调用shared.operator bool()
脱离循环并且从未检测到变化?我知道如果我只是循环一个变量,等待它达到 0 我需要volatile
,但我不确定是否boost::shared_ptr
其实现方式在这里是不必要的。
编辑:我完全意识到条件变量可以用来以不同的方式解决这个问题。但在这种情况下,繁忙循环非常罕见,并且争用条件变量上的锁是我们不希望发生的开销。
Rant 1:
该代码可能不会按照您的想法执行。当你编写这样的代码时,你正在引入一个数据竞赛到你的代码中。这几乎肯定是一个错误这将导致你的程序不确定性失败.
数据结构(包括shared_ptr)通常不适合并发访问。不要在多个线程中同时修改同一结构。这可能会破坏结构。不要在一个线程中修改它并在另一个线程中读取它。读者可能会看到不一致的数据。Probably多个线程可以同时读取它。
如果您认为确实想要执行上述某些操作,请在可能标题为“线程安全”的部分中查明数据结构是否允许其中某些行为。如果确实允许的话,再看看你的表现是否really需要这个,然后使用它。 (有关文档共享指针不允许你正在做的事情。)
Rant 2:
现在,出于更高级别的考虑,您可能不应该通过等待指针设置为 NULL 来进行线程同步。实际上,可以将条件变量、障碍或 future 视为让一个线程等待另一个线程完成某些操作的一种方式。这是一个更好的界面,无论谁接下来查看您的代码(包括 6 个月后的您)都会感谢您。
我知道您担心真正同步的性能成本。不用担心这个。会没事的。如果您担心锁争用,请使用屏障或 future,它们没有需要争用的大共享锁。
警告:有时需要编写不惜一切代价避免锁定的代码。但是,除非您查看的分析器数据表明您的同步操作对于目标工作负载来说太慢,否则现在还不是时候。
Rant 3:
我希望shared
在你的例子中是全球性的。否则,您将拥有多个线程,这些线程具有对同一对象的本地引用shared_ptr
它指向您感兴趣的真实对象。这有点违背了引用计数指针的目的。请告诉我这是全球性的。
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)