Why is the counter in boost :: shared_ptr unstable?

In the boost::shared_ptr destructor, this is done:

 if(--*pn == 0) { boost::checked_delete(px); delete pn; } 

where pn is a pointer to a reference counter, which is typed as

 shared_ptr::count_type -> detail::atomic_count -> long 

I would expect long be volatile long , given the use of threads and the non-atomic 0-check-and-deletion in the shared_ptr destructor above. Why is he not changeable?

EDIT:

Turns out I looked at the header used when multi-threaded usage is not specified (atomic_count.hpp). In atomic_count_win32.hpp, the decrement is correctly implemented for multi-threaded use.

+6
c ++ multithreading boost shared-ptr
source share
3 answers

Since volatile does not require multithreading and does nothing good, but potentially destroys a number of optimizations.

To provide secure multi-threaded access to the variable, the primitive we need is a memory barrier that provides both a volatile guarantee and several others (this prevents reordering of memory access through the barrier, t do)

I believe that shared_ptr uses atomic operations when possible, which implicitly provides a memory barrier. Otherwise, it returns to the mutex, which also provides memory protection.

See Why is volatile not considered useful for multithreaded programming in C or C ++? or http://software.intel.com/en-us/blogs/2007/11/30/volatile-almost-useless-for-multi-threaded-programming/ for more details

Edit
count_type not long in general. It is converted to long . If you look at atomic_count.hpp , typedef to long applies only if streaming is not available (in this case, of course, synchronization is not required). Otherwise, it uses the implementation defined in boost/smart_ptr/detail/atomic_count_pthreads.hpp or boost/smart_ptr/detail/atomic_count_win32.hpp , or one of the other files listed. And these are synchronized wrapper classes that ensure that all operations are performed atomically.

+16
source share

volatile has nothing to do with threading. See here .

+8
source share

You are not reading the code correctly. atomic_count is simply defined as long if the code does not use multithreading:

 #ifndef BOOST_HAS_THREADS namespace boost { namespace detail { typedef long atomic_count; } } #elif //... include various platform-specific headers that define atomic_count class #endif 
+2
source share

All Articles