shared_ptr のスレッド安全性レベルは、標準ライブラリのデフォルトレベルなので
const 操作は複数スレッドで同時に行うことができますが、更新には排他アクセスを必要とします。
しかし、より強い保証を必要とする場合がいくつかあります。
atomic な shared_ptr、つまり2つのスレッドによる同期なしの並列な更新に耐えることが可能な shared_ptr がほしいという強い要求があります(Boost MLなどで)
よくある動機は、生のポインタへの atomic な操作と、ガベージコレクションを合わせたパターンを移植したいというものです。
このケースに対応するため、
template <class T> bool atomic_is_lock_free( shared_ptr<T> const * p ); template<class T> shared_ptr<T> atomic_load( shared_ptr<T> const * p ); template<class T> shared_ptr<T> atomic_load_explicit( shared_ptr<T> const * p, memory_order mo ); template<class T> void atomic_store( shared_ptr<T> * p, shared_ptr<T> r ); template<class T> void atomic_store_explicit( shared_ptr<T> * p, shared_ptr<T> r, memory_order mo ); template<class T> shared_ptr<T> atomic_exchange( shared_ptr<T> * p, shared_ptr<T> r ); template<class T> shared_ptr<T> atomic_exchange_explicit( shared_ptr<T> * p, shared_ptr<T> r, memory_order mo ); template<class T> bool atomic_compare_exchange( shared_ptr<T> * p, shared_ptr<T> * v, shared_ptr<T> w ); template<class T> bool atomic_compare_exchange_explicit( shared_ptr<T> * p, shared_ptr<T> * v, shared_ptr<T> w, memory_order success, memory_order failure );
ちなみに、これは Boost 1.36 ですでに実装されています。
# なんで shared_ptr
以下は、典型的な "lock-free" reader/writerパターンの例
shared_ptr<State> ps; void reader() { shared_ptr<State const> p = atomic_load(&ps); // *p を使った処理... } // 単一writer void writer() { shared_ptr<State> p(new State(*ps)); // *p を更新する... atomic_store(&ps, move(p)); } // 複数writer void writer() { shared_ptr<State> p = atomic_load(&ps); do { shared_ptr<State> q(new State(*p)); // *p を更新する... } while(!atomic_compare_exchange(&ps, &p, move(q))); }
N2674 Shared_ptr atomic access, revision 1