std:: atomic
|
定義済みヘッダー
<atomic>
|
||
|
template
<
class
T
>
struct atomic ; |
(1) | (C++11以降) |
|
template
<
class
U
>
struct atomic < U * > ; |
(2) | (C++11以降) |
|
定義済みヘッダー
<memory>
|
||
|
template
<
class
U
>
struct atomic < std:: shared_ptr < U >> ; |
(3) | (C++20以降) |
|
template
<
class
U
>
struct atomic < std:: weak_ptr < U >> ; |
(4) | (C++20以降) |
|
定義済みヘッダー
<stdatomic.h>
|
||
|
#define _Atomic(T) /* 詳細は後述 */
|
(5) | (C++23以降) |
std::atomic
テンプレートの各インスタンス化および完全特殊化は、アトミック型を定義します。あるスレッドがアトミックオブジェクトに書き込みを行う間にもう一方のスレッドがそれを読み込む場合、その動作は明確に定義されます(データ競合に関する詳細は
メモリモデル
を参照してください)。
さらに、アトミックオブジェクトへのアクセスはスレッド間同期を確立し、非アトミックメモリアクセスを std::memory_order で指定された通りに順序付けることがあります。
std::atomic
はコピーもムーブもできない。
|
互換性マクロ
<stdatomic.h>
がインクルードされた際に、名前空間
|
(C++23以降) |
目次 |
特殊化
プライマリテンプレート
主要な
std::atomic
テンプレートは、
TriviallyCopyable
型
T
で、
CopyConstructible
と
CopyAssignable
の両方を満たす任意の型でインスタンス化できます。以下のいずれかの値が
false
の場合、プログラムは不適格です:
- std:: is_trivially_copyable < T > :: value
- std:: is_copy_constructible < T > :: value
- std:: is_move_constructible < T > :: value
- std:: is_copy_assignable < T > :: value
- std:: is_move_assignable < T > :: value
- std:: is_same < T, typename std:: remove_cv < T > :: type > :: value
struct Counters { int a; int b; }; // ユーザー定義のトリビアルコピー可能型 std::atomic<Counters> cnt; // ユーザー定義型に対する特殊化
std :: atomic < bool > はプライマリテンプレートを使用します。これは standard layout struct であることが保証されており、 trivial destructor を持ちます。
部分特殊化
標準ライブラリは、以下の型に対して
std::atomic
テンプレートの部分特殊化を提供しており、プライマリテンプレートにはない追加の特性を持っています:
std::atomic<U*>
は全てのポインタ型に対して提供される。これらの特殊化は標準レイアウトを持ち、
自明なデフォルトコンストラクタ、
(C++20まで)
および自明なデストラクタを持つ。全てのアトミック型に対して提供される操作に加えて、これらの特殊化はさらに、ポインタ型に適したアトミック算術操作(
fetch_add
、
fetch_sub
など)を追加でサポートする。
|
3,4)
部分特殊化
std
::
atomic
<
std::
shared_ptr
<
U
>>
および
std
::
atomic
<
std::
weak_ptr
<
U
>>
が提供される
std::shared_ptr
および
std::weak_ptr
に対して。
詳細については std::atomic <std::shared_ptr> および std::atomic <std::weak_ptr> を参照。 |
(C++20以降) |
整数型に対する特殊化
以下の整数型のいずれかでインスタンス化された場合、
std::atomic
は整数型に適した追加のアトミック操作を提供します。例えば
fetch_add
、
fetch_sub
、
fetch_and
、
fetch_or
、
fetch_xor
など:
-
- 文字型 char 、 char8_t (C++20以降) 、 char16_t 、 char32_t 、および wchar_t ;
- 標準符号付き整数型: signed char 、 short 、 int 、 long 、および long long ;
- 標準符号無し整数型: unsigned char 、 unsigned short 、 unsigned int 、 unsigned long 、および unsigned long long ;
- ヘッダー <cstdint> 内のtypedefで必要とされる追加の整数型。
さらに、結果の
std::atomic<
Integral
>
特殊化は標準レイアウトを持ち
、自明なデフォルトコンストラクタ、
(C++20まで)
および自明なデストラクタを持つ。符号付き整数演算は2の補数表現を使用するように定義されており、未定義の結果は存在しない。
浮動小数点型に対する特殊化
cv修飾されていない浮動小数点型(
float
、
double
、
long
double
およびcv修飾されていない
拡張浮動小数点型
(C++23以降)
)でインスタンス化された場合、
さらに、結果の
結果が浮動小数点型で表現できない場合でも、いかなる操作も未定義動作を引き起こしません。有効な 浮動小数点環境 は、呼び出し元スレッドの浮動小数点環境とは異なる場合があります。 |
(C++20以降) |
メンバー型
| 型 | 定義 | ||||
value_type
|
T
(特殊化されているかどうかに関わらず)
|
||||
difference_type
[1]
|
|
-
↑
difference_typeは、プライマリstd::atomicテンプレート、および std::shared_ptr と std::weak_ptr に対する部分特殊化では定義されていません。
メンバー関数
|
アトミックオブジェクトを構築する
(public member function) |
|
|
アトミックオブジェクトに値を格納する
(public member function) |
|
|
アトミックオブジェクトがロックフリーかどうかをチェックする
(public member function) |
|
|
アトミックオブジェクトの値を非アトミックな引数でアトミックに置き換える
(public member function) |
|
|
アトミックオブジェクトの値をアトミックに取得する
(public member function) |
|
|
アトミックオブジェクトから値をロードする
(public member function) |
|
|
アトミックオブジェクトの値をアトミックに置き換え、以前に保持されていた値を取得する
(public member function) |
|
|
アトミックオブジェクトの値を非アトミックな引数とアトミックに比較し、等しい場合はアトミック交換、等しくない場合はアトミックロードを実行する
(public member function) |
|
|
(C++20)
|
通知されるまで、かつアトミック値が変更されるまでスレッドをブロックする
(public member function) |
|
(C++20)
|
アトミックオブジェクトを待機している少なくとも1つのスレッドに通知する
(public member function) |
|
(C++20)
|
アトミックオブジェクトを待機しているすべてのスレッドに通知する
(public member function) |
定数 |
|
|
[static]
(C++17)
|
型が常にロックフリーであることを示す
(public static member constant) |
特殊化されたメンバー関数
整数型 、浮動小数点型 (C++20以降) およびポインタ型に特殊化 |
|
|
引数をアトミックオブジェクトに格納された値に加算し、以前に保持されていた値を取得する
(公開メンバ関数) |
|
|
アトミックオブジェクトに格納された値から引数を減算し、以前に保持されていた値を取得する
(公開メンバ関数) |
|
|
アトミック値への加算または減算を行う
(公開メンバ関数) |
|
整数型およびポインタ型のみに特殊化 |
|
|
(C++26)
|
引数とアトミックオブジェクトの値の間で
std::max
をアトミックに実行し、以前に保持されていた値を取得する
(公開メンバ関数) |
|
(C++26)
|
引数とアトミックオブジェクトの値の間で
std::min
をアトミックに実行し、以前に保持されていた値を取得する
(公開メンバ関数) |
|
アトミック値を1つインクリメントまたはデクリメントする
(公開メンバ関数) |
|
整数型のみに特殊化 |
|
|
引数とアトミックオブジェクトの値の間でビット単位ANDをアトミックに実行し、以前に保持されていた値を取得する
(公開メンバ関数) |
|
|
引数とアトミックオブジェクトの値の間でビット単位ORをアトミックに実行し、以前に保持されていた値を取得する
(公開メンバ関数) |
|
|
引数とアトミックオブジェクトの値の間でビット単位XORをアトミックに実行し、以前に保持されていた値を取得する
(公開メンバ関数) |
|
|
アトミック値とのビット単位AND、OR、XORを実行する
(公開メンバ関数) |
|
型エイリアス
boolおよび上記のすべての整数型に対して、以下のように型エイリアスが提供されています:
すべての
|
|
|
atomic_bool
(C++11)
|
std
::
atomic
<
bool
>
(typedef) |
|
atomic_char
(C++11)
|
std
::
atomic
<
char
>
(typedef) |
|
atomic_schar
(C++11)
|
std
::
atomic
<
signed
char
>
(typedef) |
|
atomic_uchar
(C++11)
|
std
::
atomic
<
unsigned
char
>
(typedef) |
|
atomic_short
(C++11)
|
std
::
atomic
<
short
>
(typedef) |
|
atomic_ushort
(C++11)
|
std
::
atomic
<
unsigned
short
>
(typedef) |
|
atomic_int
(C++11)
|
std
::
atomic
<
int
>
(typedef) |
|
atomic_uint
(C++11)
|
std
::
atomic
<
unsigned
int
>
(typedef) |
|
atomic_long
(C++11)
|
std
::
atomic
<
long
>
(typedef) |
|
atomic_ulong
(C++11)
|
std
::
atomic
<
unsigned
long
>
(typedef) |
|
atomic_llong
(C++11)
|
std
::
atomic
<
long
long
>
(typedef) |
|
atomic_ullong
(C++11)
|
std
::
atomic
<
unsigned
long
long
>
(typedef) |
|
atomic_char8_t
(C++20)
|
std
::
atomic
<
char8_t
>
(typedef) |
|
atomic_char16_t
(C++11)
|
std
::
atomic
<
char16_t
>
(typedef) |
|
atomic_char32_t
(C++11)
|
std
::
atomic
<
char32_t
>
(typedef) |
|
atomic_wchar_t
(C++11)
|
std
::
atomic
<
wchar_t
>
(typedef) |
|
atomic_int8_t
(C++11)
(オプション)
|
std
::
atomic
<
std::
int8_t
>
(typedef) |
|
atomic_uint8_t
(C++11)
(オプション)
|
std
::
atomic
<
std::
uint8_t
>
(typedef) |
|
atomic_int16_t
(C++11)
(オプション)
|
std
::
atomic
<
std::
int16_t
>
(typedef) |
|
atomic_uint16_t
(C++11)
(オプション)
|
std
::
atomic
<
std::
uint16_t
>
(typedef) |
|
atomic_int32_t
(C++11)
(オプション)
|
std
::
atomic
<
std::
int32_t
>
(typedef) |
|
atomic_uint32_t
(C++11)
(オプション)
|
std
::
atomic
<
std::
uint32_t
>
(typedef) |
|
atomic_int64_t
(C++11)
(オプション)
|
std
::
atomic
<
std::
int64_t
>
(typedef) |
|
atomic_uint64_t
(C++11)
(オプション)
|
std
::
atomic
<
std::
uint64_t
>
(typedef) |
|
atomic_int_least8_t
(C++11)
|
std
::
atomic
<
std::
int_least8_t
>
(typedef) |
|
atomic_uint_least8_t
(C++11)
|
std
::
atomic
<
std::
uint_least8_t
>
(typedef) |
|
atomic_uint_least8_t
(C++11)
|
std
::
atomic
<
std::
uint_least8_t
>
(typedef) |
|
atomic_int_least16_t
(C++11)
|
std
::
atomic
<
std::
int_least16_t
>
(typedef) |
|
atomic_uint_least16_t
(C++11)
|
std
::
atomic
<
std::
uint_least16_t
>
(typedef) |
|
atomic_int_least32_t
(C++11)
|
std
::
atomic
<
std::
int_least32_t
>
(typedef) |
|
atomic_uint_least32_t
(C++11)
|
std
::
atomic
<
std::
uint_least32_t
>
(typedef) |
|
atomic_int_least64_t
(C++11)
|
std
::
atomic
<
std::
int_least64_t
>
(typedef) |
|
atomic_uint_least64_t
(C++11)
|
std
::
atomic
<
std::
uint_least64_t
>
(typedef) |
|
atomic_int_fast8_t
(C++11)
|
std
::
atomic
<
std::
int_fast8_t
>
(typedef) |
|
atomic_uint_fast8_t
(C++11)
|
std
::
atomic
<
std::
uint_fast8_t
>
(typedef) |
|
atomic_int_fast16_t
(C++11)
|
std
::
atomic
<
std::
int_fast16_t
>
(typedef) |
|
atomic_uint_fast16_t
(C++11)
|
std
::
atomic
<
std::
uint_fast16_t
>
(typedef) |
|
atomic_int_fast32_t
(C++11)
|
std
::
atomic
<
std::
int_fast32_t
>
(typedef) |
|
atomic_uint_fast32_t
(C++11)
|
std
::
atomic
<
std::
uint_fast32_t
>
(typedef) |
|
atomic_int_fast64_t
(C++11)
|
std
::
atomic
<
std::
int_fast64_t
>
(typedef) |
|
atomic_uint_fast64_t
(C++11)
|
std
::
atomic
<
std::
uint_fast64_t
>
(typedef) |
|
atomic_intptr_t
(C++11)
(オプション)
|
std
::
atomic
<
std::
intptr_t
>
(typedef) |
|
atomic_uintptr_t
(C++11)
(オプション)
|
std
::
atomic
<
std::
uintptr_t
>
(typedef) |
|
atomic_size_t
(C++11)
|
std
::
atomic
<
std::
size_t
>
(typedef) |
|
atomic_ptrdiff_t
(C++11)
|
std
::
atomic
<
std::
ptrdiff_t
>
(typedef) |
|
atomic_intmax_t
(C++11)
|
std
::
atomic
<
std::
intmax_t
>
(typedef) |
|
atomic_uintmax_t
(C++11)
|
std
::
atomic
<
std::
uintmax_t
>
(typedef) |
|
atomic_uintmax_t
(C++11)
|
std
::
atomic
<
std::
uintmax_t
>
(typedef) |
特殊目的型のエイリアス |
|
|
atomic_signed_lock_free
(C++20)
|
ロックフリーで、待機/通知が最も効率的な符号付き整数アトミック型
(typedef) |
|
atomic_unsigned_lock_free
(C++20)
|
ロックフリーで、待機/通知が最も効率的な符号なし整数型のアトミック型
(typedef) |
std::atomic_int
N
_t
,
std::atomic_uint
N
_t
,
std::atomic_intptr_t
, and
std::atomic_uintptr_t
are defined if and only if
std::int
N
_t
,
std::uint
N
_t
,
std::intptr_t
, and
std::uintptr_t
are defined, respectively.
|
|
(C++20以降) |
注記
std::atomic
のすべてのメンバ関数には、非メンバ関数テンプレートの同等機能が存在します。これらの非メンバ関数は、
std::atomic
の特殊化ではない型であっても、アトミック性を保証できる場合に追加でオーバーロードされる可能性があります。標準ライブラリでそのような型は唯一、
std::
shared_ptr
<
U
>
です。
_Atomic
は
キーワード
であり、C言語で
アトミック型
を提供するために使用されます。
実装では、C言語における
_Atomic(T)
の表現が、あらゆる型
T
に対してC++の
std::atomic<T>
と同じであることを保証することが推奨されます。アトミック性とメモリ順序を保証するためのメカニズムは互換性を持つべきです。
GCCとClangでは、ここで説明されている機能の一部は
-latomic
へのリンクが必要です。
| 機能テスト マクロ | 値 | 標準 | 機能 |
|---|---|---|---|
__cpp_lib_atomic_ref
|
201806L
|
(C++20) |
std::atomic_ref
|
__cpp_lib_constexpr_atomic
|
202411L
|
(C++26) |
constexpr
std::atomic
および
std::atomic_ref
|
例
#include <atomic> #include <iostream> #include <thread> #include <vector> std::atomic_int acnt; int cnt; void f() { for (auto n{10000}; n; --n) { ++acnt; ++cnt; // 注: この例では、緩和されたメモリ順序で十分です // 例: acnt.fetch_add(1, std::memory_order_relaxed); } } int main() { { std::vector<std::jthread> pool; for (int n = 0; n < 10; ++n) pool.emplace_back(f); } std::cout << "The atomic counter is " << acnt << '\n' << "The non-atomic counter is " << cnt << '\n'; }
出力例:
The atomic counter is 100000 The non-atomic counter is 69696
不具合報告
以下の動作変更の欠陥報告書は、以前に公開されたC++規格に対して遡及的に適用されました。
| DR | 適用対象 | 公開時の動作 | 修正後の動作 |
|---|---|---|---|
| LWG 2441 | C++11 |
固定幅整数型のatomic版オプショナルに対するtypedefが
欠落していた |
追加された |
| LWG 3012 | C++11 |
std::atomic<T>
は自明にコピー可能だがコピー可能ではない
任意の
T
に対して許可されていた
|
そのような特殊化は禁止された |
| LWG 3949 | C++17 |
C++17で
std
::
atomic
<
bool
>
が自明なデストラクタを
持つことを要求する文言が誤って削除された |
再追加された |
|
LWG 4069
( P3323R1 ) |
C++11 |
CV修飾された
T
のサポートが疑わしかった
|
T
がCV修飾されることを禁止
|
| P0558R1 | C++11 |
アトミック型の一部の関数に対するテンプレート引数推論が
誤って失敗する可能性があった;無効なポインタ操作が 提供されていた |
仕様が大幅に書き直された:
メンバーtypedef
value_type
と
difference_type
が追加された
|
関連項目
|
(C++11)
|
ロックフリーなブーリアンアトミック型
(クラス) |
|
(C++20)
|
アトミック共有ポインタ
(クラステンプレート特殊化) |
|
(C++20)
|
アトミック弱ポインタ
(クラステンプレート特殊化) |
|
Cドキュメント
for
アトミック型
|
|