if(--*pn == 0) { boost::checked_delete(px); delete pn; }
其中pn是指向引用计数器的指针,该引用计数器的类型为
shared_ptr::count_type -> detail::atomic_count -> long
考虑到线程的使用以及上面的shared_ptr析构函数中的非原子0检查和删除,我本来期望long可以很长.为什么不变化?
编辑:
事实证明,我查看了未指定多线程使用时使用的标头(atomic_count.hpp).在atomic_count_win32.hpp中,为多线程用法正确实现了减量.
解决方法
为了确保对变量的安全多线程访问,我们需要的原语是一个内存屏障,它既提供了volatile的保证又提供了其他一些(它阻止了内存访问重新排序跨越屏障,volatile不会这样做)
我相信shared_ptr尽可能使用原子操作,这隐含地提供了内存屏障.否则它会回落到互斥锁,这也会提供内存屏障.
有关详细信息,请参阅Why is volatile not considered useful in multithreaded C or C++ programming?或http://software.intel.com/en-us/blogs/2007/11/30/volatile-almost-useless-for-multi-threaded-programming/
编辑count_type在一般情况下不长.它可以转换成很长的.如果你查看atomic_count.hpp,只有在没有可用的线程时才会应用typedef to long(在这种情况下,当然不需要同步).否则,它使用boost / smart_ptr / detail / atomic_count_pthreads.hpp或boost / smart_ptr / detail / atomic_count_win32.hpp或列出的其他文件中定义的实现.这些是同步包装类,确保所有操作都以原子方式完成.