名前空間
変種
操作

std::atomic<std::shared_ptr>

From cppreference.com
< cpp‎ | memory‎ | shared 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::shared_ptr<T>>;
(C++20以降)

std::atomicstd::shared_ptr<T>の部分特殊化により、ユーザーはshared_ptrオブジェクトをアトミックに操作できます。

複数の実行スレッドが同じstd::shared_ptrオブジェクトに同期なしでアクセスし、それらのアクセスにshared_ptrの非constメンバ関数が使用される場合、そのようなすべてのアクセスがstd::atomic<std::shared_ptr>のインスタンスを介して(または、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)
constexpr atomic( std::nullptr_t ) noexcept : atomic() {}
(2)
atomic( std::shared_ptr<T> desired ) noexcept;
(3)
atomic( const atomic& ) = delete;
(4)
1,2) 基底のshared_ptr<T>をヌル値に初期化します。
3) 基底のshared_ptr<T>desiredのコピーで初期化します。他のstd::atomic型と同様に、初期化はアトミック操作ではありません。
4) アトミック型はコピー/ムーブ構築できません。

atomic<shared_ptr<T>>::operator=

void operator=( const atomic& ) = delete;
(1)
void operator=( std::shared_ptr<T> desired ) noexcept;
(2)
void operator=( std::nullptr_t ) noexcept;
(3)
1) アトミック型はコピー/ムーブ代入できません。
2) 値の代入。store(desired)と同等です。
3) アトミックなshared_ptrをヌルポインタ値にリセットします。store(nullptr);と同等です。

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;

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

atomic<shared_ptr<T>>::load

基底のshared pointerのコピーをアトミックに返します。メモリは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>であるpに対してp.swap(desired)を実行するように、アトミックに基底のstd::shared_ptr<T>desiredに置き換え、交換直前のpの値のコピーを返します。メモリは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はアトミックオブジェクトから読み取られた既存の値で更新されます。このexpecteduse_countへの更新は、このアトミック操作の一部ですが、書き込み自体(およびその後の解放/破棄)はそうである必要はありません。
2) (1) と同じですが、偽りの失敗をする可能性もあります。
3) fail_orderorderと同じで、ただしstd::memory_order_acq_relstd::memory_order_acquireに、std::memory_order_releasestd::memory_order_relaxedに置き換えられる場合、return compare_exchange_strong(expected, desired, order, fail_order); と同等です。
4) fail_orderorderと同じで、ただしstd::memory_order_acq_relstd::memory_order_acquireに、std::memory_order_releasestd::memory_order_relaxedに置き換えられる場合、return compare_exchange_weak(expected, desired, order, fail_order); と同等です。

atomic<shared_ptr<T>>::wait

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

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

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

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

注: 2つの`shared_ptr`は、同じポインタを格納し、所有権を共有しているか、両方とも空である場合に等価です。

atomic<shared_ptr<T>>::notify_one

void notify_one() noexcept;

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

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

atomic<shared_ptr<T>>::notify_all

void notify_all() noexcept;

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

*thisでアトミック待機操作(すなわちwait())によってブロックされているスレッドがある場合、すべてのスレッドのブロックを解除します。それ以外の場合は何もしません。

[編集] メンバ定数

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

atomic<shared_ptr<T>>::is_always_lock_free

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

[編集] ノート

機能テストマクロ 規格 機能
__cpp_lib_atomic_shared_ptr 201711L (C++20) std::atomic<std::shared_ptr>

[編集]

[編集] 欠陥報告

以下の動作変更を伴う欠陥報告が、以前に公開されたC++標準に遡って適用されました。

DR 適用対象 公開された動作 正しい動作
LWG 3661 C++20 atomic<shared_ptr<T>>nullptrから定数初期化可能ではなかった 定数初期化可能になった
LWG 3893 C++20 LWG3661によりatomic<shared_ptr<T>>nullptr_tから代入できなくなった 代入可能性が回復

[編集] 関連項目

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