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>
中提供了兼容性宏
未指定当包含
<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 > 使用主模板。它被保证是一个 标准布局结构体 ,并具有 平凡析构函数 。
部分特化
标准库为以下类型提供了
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 前)
和平凡析构函数。有符号整数运算定义为使用二进制补码;不存在未定义结果。
浮点类型的特化
当使用无 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 的偏特化中定义。
成员函数
|
构造原子对象
(公开成员函数) |
|
|
向原子对象存储值
(公开成员函数) |
|
|
检查原子对象是否无锁
(公开成员函数) |
|
|
以非原子参数原子性地替换原子对象的值
(公开成员函数) |
|
|
原子性地获取原子对象的值
(公开成员函数) |
|
|
从原子对象加载值
(公开成员函数) |
|
|
原子性地替换原子对象的值并获取先前持有的值
(公开成员函数) |
|
|
原子性地比较原子对象的值与非原子参数,相等时执行原子交换,不相等时执行原子加载
(公开成员函数) |
|
|
(C++20)
|
阻塞线程直至被通知且原子值发生变化
(公开成员函数) |
|
(C++20)
|
通知至少一个等待原子对象的线程
(公开成员函数) |
|
(C++20)
|
通知所有阻塞等待原子对象的线程
(公开成员函数) |
常量 |
|
|
[static]
(C++17)
|
指示该类型始终为无锁
(公开静态成员常量) |
特化成员函数
专用于整型 、浮点型 (C++20 起) 及指针类型 |
|
|
原子地将参数与原子对象中存储的值相加,并获取先前持有的值
(公开成员函数) |
|
|
原子地从原子对象中存储的值减去参数,并获取先前持有的值
(公开成员函数) |
|
|
对原子值进行加法或减法运算
(公开成员函数) |
|
仅专用于整型及指针类型 |
|
|
(C++26)
|
原子地执行参数与原子对象值之间的
std::max
操作,并获取先前持有的值
(公开成员函数) |
|
(C++26)
|
原子地执行参数与原子对象值之间的
std::min
操作,并获取先前持有的值
(公开成员函数) |
|
将原子值递增或递减一
(公开成员函数) |
|
仅专用于整型 |
|
|
原子地在参数与原子对象值之间执行按位与操作,并获取先前持有的值
(公开成员函数) |
|
|
原子地在参数与原子对象值之间执行按位或操作,并获取先前持有的值
(公开成员函数) |
|
|
原子地在参数与原子对象值之间执行按位异或操作,并获取先前持有的值
(公开成员函数) |
|
|
对原子值执行按位与、或、异或操作
(公开成员函数) |
|
类型别名
为 bool 及上述所有整型类型提供了类型别名,如下所示:
所有
|
|
|
atomic_bool
(C++11)
|
std
::
atomic
<
bool
>
(类型定义) |
|
atomic_char
(C++11)
|
std
::
atomic
<
char
>
(typedef) |
|
atomic_schar
(C++11)
|
std
::
atomic
<
signed
char
>
(类型定义) |
|
atomic_uchar
(C++11)
|
std
::
atomic
<
unsigned
char
>
(类型定义) |
|
atomic_short
(C++11)
|
std
::
atomic
<
short
>
(类型定义) |
|
atomic_ushort
(C++11)
|
std
::
atomic
<
unsigned
short
>
(类型定义) |
|
atomic_int
(C++11)
|
std
::
atomic
<
int
>
(类型定义) |
|
atomic_uint
(C++11)
|
std
::
atomic
<
unsigned
int
>
(类型定义) |
|
atomic_long
(C++11)
|
std
::
atomic
<
long
>
(类型别名) |
|
atomic_ulong
(C++11)
|
std
::
atomic
<
unsigned
long
>
(类型别名) |
|
atomic_llong
(C++11)
|
std
::
atomic
<
long
long
>
(类型定义) |
|
atomic_ullong
(C++11)
|
std
::
atomic
<
unsigned
long
long
>
(类型定义) |
|
atomic_char8_t
(C++20)
|
std
::
atomic
<
char8_t
>
(类型别名) |
|
atomic_char16_t
(C++11)
|
std
::
atomic
<
char16_t
>
(类型别名) |
|
atomic_char32_t
(C++11)
|
std
::
atomic
<
char32_t
>
(类型别名) |
|
atomic_wchar_t
(C++11)
|
std
::
atomic
<
wchar_t
>
(类型别名) |
|
atomic_int8_t
(C++11)
(可选)
|
std
::
atomic
<
std::
int8_t
>
(类型别名) |
|
atomic_uint8_t
(C++11)
(可选)
|
std
::
atomic
<
std::
uint8_t
>
(类型别名) |
|
atomic_int16_t
(C++11)
(可选)
|
std
::
atomic
<
std::
int16_t
>
(类型定义) |
|
atomic_uint16_t
(C++11)
(可选)
|
std
::
atomic
<
std::
uint16_t
>
(类型别名) |
|
atomic_int32_t
(C++11)
(可选)
|
std
::
atomic
<
std::
int32_t
>
(类型别名) |
|
atomic_uint32_t
(C++11)
(可选)
|
std
::
atomic
<
std::
uint32_t
>
(类型别名) |
|
atomic_int64_t
(C++11)
(可选)
|
std
::
atomic
<
std::
int64_t
>
(类型别名) |
|
atomic_uint64_t
(C++11)
(可选)
|
std
::
atomic
<
std::
uint64_t
>
(类型别名) |
|
atomic_int_least8_t
(C++11)
|
std
::
atomic
<
std::
int_least8_t
>
(类型别名) |
|
atomic_uint_least8_t
(C++11)
|
std
::
atomic
<
std::
uint_least8_t
>
(类型别名) |
|
atomic_int_least16_t
(C++11)
|
std
::
atomic
<
std::
int_least16_t
>
(类型别名) |
|
atomic_uint_least16_t
(C++11)
|
std
::
atomic
<
std::
uint_least16_t
>
(类型别名) |
|
atomic_int_least32_t
(C++11)
|
std
::
atomic
<
std::
int_least32_t
>
(类型别名) |
|
atomic_uint_least32_t
(C++11)
|
std
::
atomic
<
std::
uint_least32_t
>
(类型别名) |
|
atomic_int_least64_t
(C++11)
|
std
::
atomic
<
std::
int_least64_t
>
(类型定义) |
|
atomic_uint_least64_t
(C++11)
|
std
::
atomic
<
std::
uint_least64_t
>
(类型定义) |
|
atomic_int_fast8_t
(C++11)
|
std
::
atomic
<
std::
int_fast8_t
>
(类型别名) |
|
atomic_uint_fast8_t
(C++11)
|
std
::
atomic
<
std::
uint_fast8_t
>
(类型别名) |
|
atomic_int_fast16_t
(C++11)
|
std
::
atomic
<
std::
int_fast16_t
>
(类型定义) |
|
atomic_uint_fast16_t
(C++11)
|
std
::
atomic
<
std::
uint_fast16_t
>
(类型别名) |
|
atomic_int_fast32_t
(C++11)
|
std
::
atomic
<
std::
int_fast32_t
>
(类型别名) |
|
atomic_uint_fast32_t
(C++11)
|
std
::
atomic
<
std::
uint_fast32_t
>
(类型别名) |
|
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
>
(类型别名) |
|
atomic_intptr_t
(C++11)
(可选)
|
std
::
atomic
<
std::
intptr_t
>
(类型别名) |
|
atomic_uintptr_t
(C++11)
(可选)
|
std
::
atomic
<
std::
uintptr_t
>
(类型别名) |
|
atomic_size_t
(C++11)
|
std
::
atomic
<
std::
size_t
>
(类型别名) |
|
atomic_ptrdiff_t
(C++11)
|
std
::
atomic
<
std::
ptrdiff_t
>
(类型定义) |
|
atomic_intmax_t
(C++11)
|
std
::
atomic
<
std::
intmax_t
>
(类型别名) |
|
atomic_uintmax_t
(C++11)
|
std
::
atomic
<
std::
uintmax_t
>
(类型别名) |
专用类型的别名 |
|
|
atomic_signed_lock_free
(C++20)
|
一种无锁且等待/通知操作最高效的有符号整型原子类型
(类型别名) |
|
atomic_unsigned_lock_free
(C++20)
|
一种无锁且等待/通知操作最高效的无符号整型原子类型
(类型别名) |
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)
与 C++ 中
std::atomic<T>
对于所有可能的类型
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 << "原子计数器值为 " << acnt << '\n' << "非原子计数器值为 " << cnt << '\n'; }
可能的输出:
原子计数器值为 100000 非原子计数器值为 69696
缺陷报告
以下行为变更缺陷报告被追溯应用于先前发布的 C++ 标准。
| DR | 应用于 | 发布行为 | 正确行为 |
|---|---|---|---|
| LWG 2441 | C++11 |
缺少针对
固定宽度整数类型
的原子版本 optional 的 typedef |
已添加 |
| LWG 3012 | C++11 |
std::atomic<T>
允许用于任何可平凡复制
但不可复制的
T
|
禁止此类特化 |
| LWG 3949 | C++17 |
要求
std
::
atomic
<
bool
>
具有平凡析构函数
的措辞在 C++17 中被意外删除 |
已恢复 |
|
LWG 4069
( P3323R1 ) |
C++11 |
对 cv 限定
T
的支持存在疑问
|
禁止
T
为 cv 限定类型
|
| P0558R1 | C++11 |
原子类型某些函数的模板参数推导
可能意外失败;提供了无效的指针操作 |
规范已彻底重写:
添加了成员类型定义
value_type
和
difference_type
|
另请参阅
|
(C++11)
|
无锁布尔原子类型
(类) |
|
(C++20)
|
原子共享指针
(类模板特化) |
|
(C++20)
|
原子弱指针
(类模板特化) |
|
C 文档
关于
原子类型
|
|