为什么boost :: shared_ptr中的引用计数器不是volatile?

Joh*_*ell 6 c++ multithreading boost shared-ptr

boost::shared_ptr析构函数中,这样做:

if(--*pn == 0)
{
    boost::checked_delete(px);
    delete pn;
}
Run Code Online (Sandbox Code Playgroud)

其中pn是一个指向引用计数器的指针,该指针的类型定义为

shared_ptr::count_type -> detail::atomic_count -> long
Run Code Online (Sandbox Code Playgroud)

我本来期望的longvolatile long在给定螺纹使用和非原子0检查和-删除shared_ptr上述析构函数.为什么不变化?

编辑:

事实证明,我查看了未指定多线程使用时使用的标头(atomic_count.hpp).在atomic_count_win32.hpp中,为多线程用法正确实现了减量.

jal*_*alf 16

因为volatile多线程不是必需的,并且没有任何益处,但可能会破坏许多优化.

为了确保对变量的安全多线程访问,我们需要的原语是一个内存屏障,它提供了保证volatile和其他一些(它阻止了内存访问重新排序跨越障碍,而volatile不会这样做)

我相信shared_ptr在可能的情况下使用原子操作,这隐含地提供了内存屏障.否则它会回落到互斥锁,这也会提供内存屏障.

请参阅为什么在多线程C或C++编程中volatile不被认为有用?http://software.intel.com/en-us/blogs/2007/11/30/volatile-almost-useless-for-multi-threaded-programming/了解更多详情

编辑
count_type不是一个long在一般情况下.它可以转换long.如果你查看atomic_count.hpp,只有没有可用的线程时才会应用typedef to long(在这种情况下,当然不需要同步).否则,它使用定义的实现boost/smart_ptr/detail/atomic_count_pthreads.hppboost/smart_ptr/detail/atomic_count_win32.hpp列出的其他文件或一个.这些是同步包装类,确保所有操作都以原子方式完成.


Mar*_*tos 8

volatile几乎与线程无关.看到这里.