名前空間
変種
操作

std::atomic(std::shared_ptr)

提供: cppreference.com
< cpp‎ | memory‎ | shared ptr
 
 
 
動的メモリ管理
スマートポインタ
(C++11)
(C++11)
(C++11)
(C++17未満)
(C++11)
アロケータ
メモリリソース
未初期化記憶域
(C++17)
ガベージコレクションサポート
その他
(C++20)
(C++11)
(C++11)
C のライブラリ
低水準のメモリ管理
 
 
template <class T> struct std::atomic<std::shared_ptr<T>>;
(C++20以上)

std::shared_ptr<T> に対する std::atomic のテンプレート部分特殊化は、 shared_ptr オブジェクトをアトミックに操作することを可能とします。

複数の実行のスレッドが同期せずに同じ std::shared_ptr オブジェクトにアクセスし、それらのアクセスのいずれかが shared_ptr の非 const メンバ関数を使用する場合、それらのアクセスがすべて std::atomic<std::shared_ptr<T>> のインスタンスを通して (または C++20 で非推奨になった std::shared_ptr へのアトミックアクセスのためのスタンドアロン関数を通して) 行われたのでなければ、データ競合が発生します。

関連する use_count のインクリメントは、アトミック操作の一部であることが保証されます。 関連する use_count のデクリメントは、アトミック操作に対して後続配列されますが、その一部ではありません。 ただし CAS の失敗で expected が上書きされるときの use_count は除きます。 関連するあらゆる削除および解放は、アトミック更新処理に対して後続配列され、アトミック操作の一部ではありません。

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

型 T は不完全型でも構いません。

目次

[編集] メンバ型

メンバ型 定義
value_type std::shared_ptr<T>

[編集] メンバ関数

std::atomic の特殊化されていないすべての関数は、この特殊化でも提供されます。 追加のメンバ関数はありません。

atomic<shared_ptr<T>>::atomic

constexpr atomic() noexcept = default;
(1)
atomic(std::shared_ptr<T> desired) noexcept;
(2)
atomic(const atomic&) = delete;
(3)
1) ベースとなる shared_ptr<T> をデフォルト構築された値に初期化します。
2) ベースとなる shared_ptr<T>desired のコピーに初期化します。 あらゆる std::atomic 型同様、初期化はアトミック操作ではありません。
3) アトミック型はコピー構築可能でもムーブ構築可能でもありません。

atomic<shared_ptr<T>>::operator=

void operator=(const atomic&) = delete;
(1)
void operator=(std::shared_ptr<T> desired) noexcept;
(2)
1) アトミック型はコピー代入可能でもムーブ代入可能でもありません。
2) 値の代入。 store(desired) と同等です。

atomic<shared_ptr<T>>::is_lock_free

bool is_lock_free() const noexcept;

この型のすべてのオブジェクトに対するアトミック操作がロックリーであれば true、そうでなければ false を返します。

atomic<shared_ptr<T>>::store

void store(std::shared_ptr<T> desired,
           std::memory_order order = std::memory_order_seq_cst) noexcept;

*this の値を desired の値とアトミックに置き換えます。 置き換えは p.swap(desired) によって行われたかのように行われます。 ただし p はベースとなる std::shared_ptr<T> です。 メモリは order に従って順序付けされます。 orderstd::memory_order_consumestd::memory_order_acquire、 または std::memory_order_acq_rel の場合、動作は未定義です。

atomic<shared_ptr<T>>::load

ベースとなる shared_ptr のコピーをアトミックに返します。 メモリは order に従って順序付けされます。 orderstd::memory_order_release または std::memory_order_acq_rel の場合、動作は未定義です。

atomic<shared_ptr<T>>::operator std::shared_ptr<T>

operator std::shared_ptr<T>() const noexcept;

return load(); と同等です。

atomic<shared_ptr<T>>::exchange

std::shared_ptr<T> exchange(std::shared_ptr<T> desired,
                            std::memory_order order = std::memory_order_seq_cst) noexcept;

ベースとなる std::shared_ptr<T>desired でアトミックに置き換え、 p がその置き換えの直前に持っていた値のコピーを返します。 置き換えは p.swap(desired) によって行われたかのように行われます。 ただし p はベースとなる std::shared_ptr<T> です。 メモリは order に従って順序付けされます。 これはアトミック読み込み-変更-書き込み操作です。

atomic<shared_ptr<T>>::compare_exchange_weak, compare_exchange_strong

bool compare_exchange_strong(std::shared_ptr<T>& expected, std::shared_ptr<T> desired,
                             std::memory_order success, std::memory_order failure) noexcept;
(1)
bool compare_exchange_weak(std::shared_ptr<T>& expected, std::shared_ptr<T> desired,
                           std::memory_order success, std::memory_order failure) noexcept;
(2)
bool compare_exchange_strong(std::shared_ptr<T>& expected, std::shared_ptr<T> desired,
                             std::memory_order order = std::memory_order_seq_cst) noexcept;
(3)
bool compare_exchange_weak(std::shared_ptr<T>& expected, std::shared_ptr<T> desired,
                           std::memory_order order = std::memory_order_seq_cst) noexcept;
(4)
1) ベースとなる std::shared_ptr<T>expected と同じ T* を格納していて、それと所有権を共有している場合、または、ベースと expected がどちらも空の場合、 desired からベースとなる std::shared_ptr<T> に代入を行い、 true を返し、 success に従ってメモリを順序付けします。 そうでなければ、ベースとなる std::shared_ptr<T> から expected に代入を行い、 false を返し、 failure に従ってメモリを順序付けします。 failurestd::memory_order_release または std::memory_order_acq_rel であれば、動作は未定義です。 成功した場合、この操作は *this に対するアトミック読み込み-変更-書き込み操作であり、アトミック更新後 expected はアクセスされません。 失敗した場合、この操作は *this に対するアトミックロード操作であり、 expected はそのアトミックオブジェクトから読み込んだ既存の値で更新されます。 expected の use_count に対する更新はこのアトミック操作の一部ですが、書き込み自体 (および後続の解放/削除) はそうであるとは限りません。
2) (1) と同じですが、スプリアスに失敗する可能性があります。
3) return compare_exchange_strong(expected, desired, order, fail_order); と同等です。 ただし fail_orderorder と同じですが、 std::memory_order_acq_relstd::memory_order_acquire に置き換えられ、 std::memory_order_releasestd::memory_order_relaxed に置き換えられます。
4) return compare_exchange_weak(expected, desired, order, fail_order); と同等です。 ただし fail_orderorder と同じですが、 std::memory_order_acq_relstd::memory_order_acquire に置き換えられ、 std::memory_order_releasestd::memory_order_relaxed に置き換えられます。

[編集] メンバ定数

唯一の標準の std::atomic のメンバ定数 is_always_lock_free は、この特殊化によっても提供されます。

atomic<shared_ptr<T>>::is_always_lock_free

static constexpr bool is_always_lock_free = /*implementation-defined*/;

[編集]

[編集] 関連項目

(C++11)
atomic クラステンプレートと bool 型、整数型、ポインタ型に対する特殊化
(クラステンプレート) [edit]