Atomic types
目录 |
语法
_Atomic
(
类型名称
)
|
(1) | (自 C11 起) | |||||||
_Atomic
类型名称
|
(2) | (自 C11 起) | |||||||
const
、
volatile
和
restrict
混合使用,但与其他限定符不同的是,
type-name
的原子版本可能具有不同的大小、对齐方式和对象表示形式。
| 类型名称 | - | 除数组或函数外的任意类型。对于 (1) , 类型名称 也不能是原子类型或带有cv限定符的类型 |
头文件 <stdatomic.h> 定义了 众多便捷类型别名 ,从 atomic_bool 到 atomic_uintmax_t ,这些别名简化了该关键字与内置类型及库类型的使用。
_Atomic const int* p1; // p1 是指向原子常量整数的指针 const atomic_int* p2; // 同上 const _Atomic(int)* p3; // 同上
如果编译器定义了宏常量 __STDC_NO_ATOMICS__ ,则不会提供关键字 _Atomic 。
说明
原子类型的对象是唯一不受 数据竞争 影响的对象;也就是说,它们可以被两个线程并发修改,或者被一个线程修改的同时被另一个线程读取。
每个原子对象都有其自身的
修改顺序
,这是对该对象进行修改的全序。如果从某个线程的视角来看,某个原子对象
M
的修改
A
先于
同一原子对象
M
的修改
B
发生,那么在
M
的修改顺序中,
A
将位于
B
之前。
请注意,尽管每个原子对象都有其自身的修改顺序,但不存在单一的总顺序;不同线程可能以不同顺序观察到对不同原子对象的修改。
所有原子操作保证具有四种一致性类型:
-
写-写连贯性
:若修改原子对象
M的操作A先发生于 修改M的操作B,则A在M的修改顺序中早于B出现。 -
读-读连贯性
:若原子对象
M的值计算A先发生于M的值计算B,且A从M的副作用X获取其值,则B计算得出的值要么是X存储的值,要么是M的副作用Y存储的值,其中Y在M的修改顺序中晚于X出现。 -
读-写连贯性
:若原子对象
M的值计算A先发生于M上的操作B,则A从M的副作用X获取其值,其中X在M的修改顺序中早于B出现。 -
写-读连贯性
:若原子对象
M的副作用X先发生于M的值计算B,则计算B从X或从在M的修改顺序中晚于X出现的副作用Y获取其值。
某些原子操作同时也是同步操作;它们可能具有额外的释放语义、获取语义或顺序一致语义。请参阅 memory_order 。
内置的 递增和递减运算符 以及 复合赋值运算符 是具有完全顺序一致排序的读-修改-写原子操作(如同使用 memory_order_seq_cst )。若需要更宽松的同步语义,可以使用 标准库函数 作为替代。
原子属性仅对 左值表达式 有意义。左值到右值的转换(模拟从原子位置到CPU寄存器的内存读取操作)会剥离原子性及其他限定符。
|
本节内容不完整
原因:需补充更多内容,并审阅与memory_order及原子库页面的交互说明 |
注释
访问原子结构体/联合体的成员是未定义行为。
库类型 sig_atomic_t 不提供线程间同步或内存排序,仅保证原子性。
volatile
类型不提供线程间同步、内存排序或原子性保证。
建议实现确保C语言中的
_Atomic
(
T
)
表示与C++中
std
::
atomic
<
T
>
对每个可能类型
T
的表示保持一致。用于确保原子性和内存顺序的机制应当相互兼容。
关键词
示例
#include <stdatomic.h> #include <stdio.h> #include <threads.h> atomic_int acnt; int cnt; int f(void* thr_data) { for (int n = 0; n < 1000; ++n) { ++cnt; ++acnt; // 对于此示例,宽松内存序已足够,例如: // atomic_fetch_add_explicit(&acnt, 1, memory_order_relaxed); } return 0; } int main(void) { thrd_t thr[10]; for (int n = 0; n < 10; ++n) thrd_create(&thr[n], f, NULL); for (int n = 0; n < 10; ++n) thrd_join(thr[n], NULL); printf("The atomic counter is %u\n", acnt); printf("The non-atomic counter is %u\n", cnt); }
可能的输出:
The atomic counter is 10000 The non-atomic counter is 8644
参考文献
- C23 标准 (ISO/IEC 9899:2024):
-
- 6.7.2.4 原子类型说明符 (p: TBD)
-
- 7.17 原子操作 <stdatomic.h> (p: TBD)
- C17 标准 (ISO/IEC 9899:2018):
-
- 6.7.2.4 原子类型说明符 (p: 87)
-
- 7.17 原子操作 <stdatomic.h> (p: 200-209)
- C11 标准 (ISO/IEC 9899:2011):
-
- 6.7.2.4 原子类型说明符 (p: 121)
-
- 7.17 原子操作 <stdatomic.h> (p: 273-286)
参见
| 并发支持库 | |
|
C++ 文档
关于
atomic
|