std::atomic_...<std::shared_ptr> - cppreference.com
<tbody> </tbody>
|
|
(1) | (C++11以上) (C++20で非推奨) |
|
|
(2) | (C++11以上) (C++20で非推奨) |
|
|
(3) | (C++11以上) (C++20で非推奨) |
|
|
(4) | (C++11以上) (C++20で非推奨) |
|
|
(5) | (C++11以上) (C++20で非推奨) |
|
|
(6) | (C++11以上) (C++20で非推奨) |
|
|
(7) | (C++11以上) (C++20で非推奨) |
|
|
(8) | (C++11以上) (C++20で非推奨) |
|
|
(9) | (C++11以上) (C++20で非推奨) |
|
|
(10) | (C++11以上) (C++20で非推奨) |
|
|
(11) | (C++11以上) (C++20で非推奨) |
複数の実行のスレッドが同期せずに同じ std::shared_ptr オブジェクトにアクセスし、それらのアクセスのいずれかが shared_ptr の非 const メンバ関数を使用する場合、それらのアクセスがすべてこれらの関数を通して行われたのでなければ、データ競合が発生します。 これらの関数は、対応するアトミック関数 (std::atomic_load や std::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 がヌルポインタの場合、未定義動作を発生させます。
引数
| 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 テンプレートの特殊化 |
(C++20以上) |
例
欠陥報告
以下の動作変更欠陥報告は以前に発行された C++ 標準に遡って適用されました。
| DR | 適用先 | 発行時の動作 | 正しい動作 |
|---|---|---|---|
| LWG 2980 | C++11 | empty shared_ptrs are never equivalent
|
equivalent if they store the same pointer value |