std:: atomic <std::shared_ptr>
|
ヘッダーで定義
<memory>
|
||
|
template
<
class
T
>
struct std:: atomic < std:: shared_ptr < T >> ; |
(C++20以降) | |
std::atomic
の部分テンプレート特殊化は、
std::
shared_ptr
<
T
>
に対して行われ、ユーザーが
shared_ptr
オブジェクトをアトミックに操作することを可能にします。
複数の実行スレッドが同期なしに同じ std::shared_ptr オブジェクトにアクセスし、そのいずれかのアクセスが shared_ptr の非constメンバ関数を使用する場合、そのようなアクセスすべてが std:: atomic < std:: shared_ptr > のインスタンスを通じて実行されない限り、データ競合が発生します(または、C++20以降では非推奨となった standalone functions を通じて 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 関数はこの特殊化によっても提供され、追加のメンバ関数はありません。
|
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) | |
|
void
operator
=
(
const
atomic
&
)
=
delete
;
|
(1) | |
|
void
operator
=
(
std::
shared_ptr
<
T
>
desired
)
noexcept
;
|
(2) | |
|
void
operator
=
(
std::
nullptr_t
)
noexcept
;
|
(3) | |
|
bool
is_lock_free
(
)
const
noexcept
;
|
||
この型のすべてのオブジェクトに対するアトミック操作がロックフリーである場合 true を返し、そうでない場合 false を返します。
|
void
store
(
std::
shared_ptr
<
T
>
desired,
std:: memory_order order = std:: memory_order_seq_cst ) noexcept ; |
||
*this
の値を
desired
の値でアトミックに置き換えます。これは、基盤となる
std::shared_ptr<T>
である
p
に対して
p.swap(desired)
を実行するのと同様です。メモリは
order
に従って順序付けられます。
order
が
std::memory_order_consume
、
std::memory_order_acquire
、または
std::memory_order_acq_rel
の場合、動作は未定義です。
|
std::
shared_ptr
<
T
>
load
(
std::
memory_order
order
=
std::
memory_order_seq_cst
)
const
noexcept
;
|
||
基となるshared_ptrのコピーをアトミックに返します。メモリ順序は order に従って順序付けられます。 order が std::memory_order_release または std::memory_order_acq_rel の場合、動作は未定義です。
|
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. swap ( desired ) を実行したかのように動作します。ここで p は基となる std:: shared_ptr < T > です。また、交換直前に p が保持していた値のコピーを返します。メモリ順序は order に従って順序付けられます。これはアトミックなread-modify-write操作です。
|
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) | |
use_count
に対するこの更新はこの原子的操作の一部であるが、書き込み自体(およびそれに続く解放/破棄)は必須ではない。
fail_order
は
order
と同じであるが、
std::memory_order_acq_rel
が
std::memory_order_acquire
に置き換えられ、
std::memory_order_release
が
std::memory_order_relaxed
に置き換えられる点が異なる。
fail_order
は、
order
と同じであるが、
std::memory_order_acq_rel
が
std::memory_order_acquire
に置き換えられ、
std::memory_order_release
が
std::memory_order_relaxed
に置き換えられる点が異なる。
|
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 に従って順序付けられます。 order が std::memory_order_release または std::memory_order_acq_rel の場合、動作は未定義です。
注記: 2つの
shared_ptr
は、同じポインタを格納しており、かつ所有権を共有しているか、両方が空である場合に等価となります。
|
void
notify_one
(
)
noexcept
;
|
||
アトミックな通知操作を実行します。
*
this
に対するアトミック待機操作(すなわち
wait()
)でブロックされているスレッドが存在する場合、少なくとも1つのそのようなスレッドのブロックを解除します。それ以外の場合は何も行いません。
|
void
notify_all
(
)
noexcept
;
|
||
アトミックな通知操作を実行します。
*
this
上のアトミック待機操作(すなわち
wait()
)でブロックされているスレッドがあれば、それらすべてのブロックを解除します。そうでない場合は何も行いません。
メンバー定数
唯一の標準
std::atomic
メンバー定数
is_always_lock_free
もこの特殊化によって提供されます。
|
static
constexpr
bool
is_always_lock_free
=
/*implementation-defined*/
;
|
||
注記
| 機能テスト マクロ | 値 | 標準 | 機能 |
|---|---|---|---|
__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以降)
およびポインタ型に対するatomicクラステンプレートと特殊化
(クラステンプレート) |