名前空間
変種
操作

std::atomic_...<std::shared_ptr>

提供: cppreference.com
< cpp‎ | memory‎ | shared ptr
 
 
 
動的メモリ管理
未初期化記憶域
(C++17)
ガベージコレクションサポート
その他
(C++20)
(C++11)
(C++11)
C のライブラリ
低水準のメモリ管理
 
 
template< class T >
bool atomic_is_lock_free( const std::shared_ptr<T>* p );
(1) (C++11およびそれ以降)
(C++20で非推奨)
template< class T >
std::shared_ptr<T> atomic_load( const std::shared_ptr<T>* p );
(2) (C++11およびそれ以降)
(C++20で非推奨)
template< class T >

std::shared_ptr<T> atomic_load_explicit( const std::shared_ptr<T>* p,

                                         std::memory_order mo );
(3) (C++11およびそれ以降)
(C++20で非推奨)
template< class T >

void atomic_store( std::shared_ptr<T>* p,

                   std::shared_ptr<T> r );
(4) (C++11およびそれ以降)
(C++20で非推奨)
template< class T >

void atomic_store_explicit( std::shared_ptr<T>* p,
                            std::shared_ptr<T> r,

                            std::memory_order mo);
(5) (C++11およびそれ以降)
(C++20で非推奨)
template< class T >

std::shared_ptr<T> atomic_exchange( std::shared_ptr<T>* p,

                                    std::shared_ptr<T> r);
(6) (C++11およびそれ以降)
(C++20で非推奨)
template<class T>

std::shared_ptr<T> atomic_exchange_explicit( std::shared_ptr<T>* p,
                                             std::shared_ptr<T> r,

                                             std::memory_order mo);
(7) (C++11およびそれ以降)
(C++20で非推奨)
template< class T >

bool atomic_compare_exchange_weak( std::shared_ptr<T>* p,
                                   std::shared_ptr<T>* expected,

                                   std::shared_ptr<T> desired);
(8) (C++11およびそれ以降)
(C++20で非推奨)
template<class T>

bool atomic_compare_exchange_strong( std::shared_ptr<T>* p,
                                     std::shared_ptr<T>* expected,

                                     std::shared_ptr<T> desired);
(9) (C++11およびそれ以降)
(C++20で非推奨)
template< class T >

bool atomic_compare_exchange_strong_explicit( std::shared_ptr<T>* p,
                                              std::shared_ptr<T>* expected,
                                              std::shared_ptr<T> desired,
                                              std::memory_order success,

                                              std::memory_order failure);
(10) (C++11およびそれ以降)
(C++20で非推奨)
template< class T >

bool atomic_compare_exchange_weak_explicit( std::shared_ptr<T>* p,
                                            std::shared_ptr<T>* expected,
                                            std::shared_ptr<T> desired,
                                            std::memory_order success,

                                            std::memory_order failure);
(11) (C++11およびそれ以降)
(C++20で非推奨)

複数の実行のスレッドが同期せずに同じ std::shared_ptr オブジェクトにアクセスし、それらのアクセスのいずれかが shared_ptr の非 const メンバ関数を使用する場合、それらのアクセスがすべてこれらの関数を通して行われたのでなければ、データ競合が発生します。 これらの関数は、対応するアトミック関数 (std::atomic_loadstd::atomic_store など) のオーバーロードです。

shared_ptr の制御ブロックはスレッドセーフであることに注意してください。 異なる std::shared_ptr オブジェクトは、これらのインスタンスがコピーされ内部的に同じ制御ブロックを共有しているときでも、 operator= や reset といった変更操作を使用して複数のスレッドから同時にアクセスできます。

1) p の指す shared_ptr へのアトミックアクセスがロックフリーかどうか調べます。
2) atomic_load_explicit(p, std::memory_order_seq_cst) と同等です。
3) p の指す shared_ptr を返します。 特殊化されていない std::atomic_load_explicit と同様、 mo には std::memory_order_release および std::memory_order_acq_rel を指定できません。
4) atomic_store_explicit(p, r, memory_order_seq_cst) と同等です。
5) p の指す shared_ptr に r をアトミックに格納します。 実質的に p->swap(r) を実行します。 特殊化されていない std::atomic_store_explicit と同様、 mo には std::memory_order_acquire および std::memory_order_acq_rel を指定できません。
6) atomic_exchange_explicit(p, r, memory_order_seq_cst) と同等です。
7) アトミックに、 p の指す shared_ptr に r を格納し、 p の指す先がそれまで保持していた値を返します。 実質的に p->swap(r) を実行し、その swap 後の r のコピーを返します。
8) atomic_compare_exchange_weak_explicit(p, expected, desired, std::memory_order_seq_cst, std::memory_order_seq_cst) と同等です。
9) atomic_compare_exchange_strong_explicit(p, expected, desired, std::memory_order_seq_cst, std::memory_order_seq_cst) と同等です。
10) p の指す shared_ptr と expected を比較します。 それらが同等 (同じポインタ値を格納し、同じオブジェクトの所有権を共有するかどちらも空) であれば、 success で指定されたメモリ順序制約を用いて、 desired*p に代入し、 true を返します。 同等でなければ、 failure で指定されたメモリ順序制約を用いて、 *p*expected に代入し、 false を返します。
11) 10) と同じですが、スプリアスに失敗する可能性があります。

これらの関数はすべて、 p が NULL ポインタの場合、未定義動作を発生させます。

目次

[編集] 引数

p, expected - std::shared_ptr を指すポインタ
r, desired - std::shared_ptr
mo, success, failure - std::memory_order 型のメモリ順序制約

[編集] 例外

これらの関数は例外を投げません。

[編集] 戻り値

1) アトミックアクセスがロックフリー命令で実装されている場合は true
2,3) 指している shared_ptr のコピー。
4,5) (なし)
6,7) 指している shared_ptr がそれまで保持していた値のコピー。
8,9,10,11) shared_ptr が同等で、交換が実行された場合は true。 そうでなければ false

[編集] ノート

これらの関数は一般的に、ポインタ値をキーとして使用したグローバルなハッシュテーブルに格納されているミューテックスを使用して、実装されています。

データ競合を避けるためには、いったん shared_ptr をこれらの関数のいずれかに渡したら、以降、非アトミックにアクセスすることはできません。 特に、そのような shared_ptr を直接逆参照することはできません。 まずその shared_ptr を別の shared_ptr にアトミックロードし、それからそのロードした shared_ptr を通して逆参照する必要があります。

Concurrency TS は、これらの関数の置き換えとして、アトミックなスマートポインタクラス atomic_shared_ptr および atomic_weak_ptr を提案しています。

std::atomic テンプレートの特殊化 std::atomic<std::shared_ptr> および std::atomic<std::weak_ptr> の方が好ましいため、これらの関数は非推奨になりました。

(C++20およびそれ以降)

[編集]

[編集] 欠陥報告

以下の動作変更欠陥報告は以前に発行された C++ 標準に遡って適用されました。

DR 適用先 発行時の動作 正しい動作
LWG 2980 C++11 empty shared_ptrs are never equivalent equivalent if they store the same pointer value

[編集] 関連項目

アトミック型の操作がロックフリーかどうか調べます
(関数テンプレート) [edit]
アトミックオブジェクトの値を非アトミック引数でアトミックに置き換えます
(関数テンプレート) [edit]
アトミックオブジェクトに格納されている値をアトミックに取得します
(関数テンプレート) [edit]
アトミックオブジェクトの値を非アトミック引数でアトミックに置き換え、そのアトミックの古い値を返します
(関数テンプレート) [edit]
アトミックに、アトミックオブジェクトの値を非アトミック引数と比較し、等しければ交換を行い、等しくなければ読み込みます
(関数テンプレート) [edit]