名前空間
変種
操作

std::atomic<std::weak_ptr>

From cppreference.com
< cpp‎ | memory‎ | weak ptr
 
 
メモリ管理ライブラリ
(説明用*)
未初期化メモリのアルゴリズム
(C++17)
(C++17)
(C++17)
制約付き未初期化
メモリアルゴリズム
Cライブラリ

アロケータ
メモリリソース
ガベージコレクションのサポート
(C++11)(C++23まで)
(C++11)(C++23まで)
(C++11)(C++23まで)
(C++11)(C++23まで)
(C++11)(C++23まで)
(C++11)(C++23まで)
未初期化ストレージ
(C++20まで*)
(C++20まで*)
明示的な生存期間管理
 
 
ヘッダ <memory> で定義
template< class T > struct std::atomic<std::weak_ptr<T>>;
(C++20以降)

std::atomicstd::weak_ptr<T> に対する部分テンプレート特殊化により、ユーザーは `weak_ptr` オブジェクトをアトミックに操作できます。

複数の実行スレッドが同期なしに同じ std::weak_ptr オブジェクトにアクセスし、かつそれらのアクセスの中に `weak_ptr` の非 `const` メンバ関数のいずれかを使用するものがある場合、データ競合が発生します。ただし、そのようなアクセスがすべて std::atomic<std::weak_ptr> のインスタンスを通じて行われる場合は除きます。

関連する `use_count` のインクリメントは、アトミック操作の一部であることが保証されます。関連する `use_count` のデクリメントは、アトミック操作より後に順序付けられますが、それの一部である必要はありません。ただし、失敗した CAS で `expected` を上書きする場合の `use_count` の変更は例外です。関連する削除および解放は、アトミック更新ステップより後に順序付けられ、アトミック操作の一部ではありません。

std::weak_ptr および std::shared_ptr によって使用される制御ブロックはスレッドセーフです。異なる非アトミックな std::weak_ptr オブジェクトは、`operator=` や `reset` のようなミュータブルな操作を使用して、複数のスレッドから同時にアクセスされる可能性があります。たとえこれらのインスタンスがコピーであったり、内部で同じ制御ブロックを共有していたとしても同様です。

T は不完全型である可能性があります。

目次

[編集] メンバ型

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

[編集] メンバ関数

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

atomic<weak_ptr<T>>::atomic

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

atomic<weak_ptr<T>>::operator=

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

atomic<weak_ptr<T>>::is_lock_free

bool is_lock_free() const noexcept;

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

atomic<weak_ptr<T>>::store

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

アトミックに `*this` の値を `desired` の値で置き換えます。これは、`p` が基になる std::weak_ptr<T> であるような `p.swap(desired)` と同等です。メモリは `order` に従って順序付けられます。`order` が std::memory_order_consumestd::memory_order_acquire、または std::memory_order_acq_rel の場合、動作は未定義です。

atomic<weak_ptr<T>>::load

基になる std::weak_ptr<T> のコピーをアトミックに返します。メモリは `order` に従って順序付けられます。`order` が std::memory_order_release または std::memory_order_acq_rel の場合、動作は未定義です。

atomic<weak_ptr<T>>::operator std::weak_ptr<T>

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

return load(); と同等。

atomic<weak_ptr<T>>::exchange

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

基になる std::weak_ptr<T> を `desired` でアトミックに置き換えます。これは、`p` が基になる std::weak_ptr<T> であるような `p.swap(desired)` と同等であり、`p` がスワップ直前に持っていた値のコピーを返します。メモリは `order` に従って順序付けられます。これはアトミックな読み取り-変更-書き込み操作です。

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

bool compare_exchange_strong(std::weak_ptr<T>& expected, std::weak_ptr<T> desired,
                             std::memory_order success, std::memory_order failure) noexcept;
(1)
bool compare_exchange_weak(std::weak_ptr<T>& expected, std::weak_ptr<T> desired,
                           std::memory_order success, std::memory_order failure) noexcept;
(2)
bool compare_exchange_strong(std::weak_ptr<T>& expected, std::weak_ptr<T> desired,
                             std::memory_order order = std::memory_order_seq_cst) noexcept;
(3)
bool compare_exchange_weak(std::weak_ptr<T>& expected, std::weak_ptr<T> desired,
                           std::memory_order order = std::memory_order_seq_cst) noexcept;
(4)
1) 基になる std::weak_ptr<T> が `expected` と同じポインタ値を格納しており、所有権を共有している場合、または基になるものと `expected` の両方が空の場合、`desired` から基になる std::weak_ptr<T> に代入し、`true` を返します。メモリは `success` に従って順序付けられます。それ以外の場合、基になる std::weak_ptr<T> から `expected` に代入し、`false` を返します。メモリは `failure` に従って順序付けられます。`failure` が std::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_order` は `order` と同じですが、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_order` は `order` と同じですが、std::memory_order_acq_relstd::memory_order_acquire に置き換えられ、std::memory_order_releasestd::memory_order_relaxed に置き換えられます。

atomic<weak_ptr<T>>::wait

void wait(std::weak_ptr<T> old
          std::memory_order order = std::memory_order_seq_cst) const noexcept;

アトミックな待機操作を実行します。

`load(order)` を `old` と比較し、それらが等しい場合は `*this` が `notify_one()` または `notify_all()` によって通知されるまでブロックします。これは `load(order)` の値が変更されるまで繰り返されます。この関数は、基になる実装が偽にアンブロックした場合でも、値が変更された場合にのみ戻ることが保証されます。

メモリは `order` に従って順序付けられます。`order` が std::memory_order_release または std::memory_order_acq_rel の場合、動作は未定義です。

注: 2つの std::weak_ptr は、それらが同じポインタを格納し、所有権を共有しているか、または両方が空である場合に等しいとみなされます。

atomic<weak_ptr<T>>::notify_one

void notify_one() noexcept;

アトミックな通知操作を実行します。

アトミックな待機操作(つまり `wait()`)で `*this` でブロックされているスレッドがある場合、少なくとも 1 つのスレッドをアンブロックします。それ以外の場合は何も行いません。

atomic<weak_ptr<T>>::notify_all

void notify_all() noexcept;

アトミックな通知操作を実行します。

`*this` でアトミックな待機操作(つまり `wait()`)でブロックされているすべてのスレッドをアンブロックします。ブロックされているスレッドがない場合は何も行いません。

[編集] メンバ定数

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

atomic<weak_ptr<T>>::is_always_lock_free

static constexpr bool is_always_lock_free = /*実装定義*/;

[編集]

[編集] 関連項目

(C++11)
アトミッククラステンプレートと、bool、整数、浮動小数点数、(C++20以降)、ポインタ型のための特殊化
(クラステンプレート) [編集]
English 日本語 中文(简体) 中文(繁體)