# C 语言标准库头文件 stdatomic.h
这个头文件提供 原子操作 的相关功能。原子操作是指在并发环境中,一个不可分割的操作,它要么完全执行完毕,要么完全不执行,不会出现执行到一半被其他线程或进程打断的情况。
# 示例
#include <stdio.h>
#include <stdatomic.h>
#include <threads.h> // C11 多线程标准头文件
atomic_int counter = 0; // 计数器,原子类型
// 线程函数,增加计数器
int increment(void* arg) {
int loops = *(int*)arg;
for (int i = 0; i < loops; i++) {
// 原子操作-加一
atomic_fetch_add(&counter, 1);
}
return 0;
}
int main(void) {
// 原子操作-比较交换:如果 counter 等于 expected,则将 counter 设为 10
int expected = 0;
if (atomic_compare_exchange_strong(&counter, &expected, 10)) {
printf("counter 的值是 0, 现在将其设为 10\n");
}
// 创建多个线程
thrd_t t1, t2;
int loops = 100000;
thrd_create(&t1, increment, &loops);
thrd_create(&t2, increment, &loops);
// 等待线程结束
thrd_join(t1, NULL);
thrd_join(t2, NULL);
printf("最终 counter 的值是: %d\n", atomic_load(&counter));
return 0;
}
运行结果:
counter 的值是 0, 现在将其设为 10
最终 counter 的值是: 200010
# 类型
| 类型 |
标准 |
说明 |
atomic_flag |
C11 |
一个特殊的原子布尔类型,保证无锁但不提供加载或存储操 |
memory_order |
C11 |
内存顺序 的枚举 |
| 宏 |
标准 |
说明 |
ATOMIC_BOOL_LOCK_FREE |
C11 |
表示 atomic_bool 类型的原子操作是否是无锁的,0 表示不是无锁,1 表示有时无锁,2表示始终无锁,下同 |
ATOMIC_CHAR_LOCK_FREE |
C11 |
表示 atomic_char 类型的原子操作是否是无锁的 |
ATOMIC_CHAR8_T_LOCK_FREE |
C23 |
表示 atomic_char8_t 类型的原子操作是否是无锁的 |
ATOMIC_CHAR16_T_LOCK_FREE |
C11 |
表示 atomic_char16_t 类型的原子操作是否是无锁的 |
ATOMIC_CHAR32_T_LOCK_FREE |
C11 |
表示 atomic_char32_t 类型的原子操作是否是无锁的 |
ATOMIC_WCHAR_T_LOCK_FREE |
C11 |
表示 atomic_wchar_t 类型的原子操作是否是无锁的 |
ATOMIC_SHORT_LOCK_FREE |
C11 |
表示 atomic_short 类型的原子操作是否是无锁的 |
ATOMIC_INT_LOCK_FREE |
C11 |
表示 atomic_int 类型的原子操作是否是无锁的 |
ATOMIC_LONG_LOCK_FREE |
C11 |
表示 atomic_long 类型的原子操作是否是无锁的 |
ATOMIC_LLONG_LOCK_FREE |
C11 |
表示 atomic_llong 类型的原子操作是否是无锁的 |
ATOMIC_POINTER_LOCK_FREE |
C11 |
表示指针类型的原子操作是否是无锁的 |
# 函数
| 函数 |
标准 |
说明 |
atomic_init |
C11 |
初始化一个原子对象,并指定 内存顺序 |
ATOMIC_VAR_INIT |
C11(在 C17 废弃) |
初始化一个原子变量,实际上直接赋值即可 |
ATOMIC_FLAG_INIT |
C11 |
初始化一个 atomic_flag |
kill_dependency |
C11 |
通知编译器 memory_order_consume 的原子操作不依赖某个值 |
atomic_thread_fence |
C11 |
在当前线程插入一个 内存顺序 屏障 |
atomic_signal_fence |
C11 |
在当前线程和信号处理程序之间插入一个 内存顺序 屏障 |
| 原子操作 |
标准 |
说明 |
atomic_is_lock_free |
C11 |
判断对象是否是无锁的 |
atomic_store |
C11 |
原子地将值存入对象 |
atomic_load |
C11 |
原子地读取对象 |
atomic_exchange |
C11 |
原子地将值与对象交换 |
atomic_compare_exchange_weak |
C11 |
原子地将值 A 与对象比较,如果相等则将值 B 与对象交换,可能虚假地失败,速度更快,常用于循环中 |
atomic_compare_exchange_strong |
C11 |
原子地将值 A 与对象比较,如果相等则将值 B 与对象交换 |
atomic_fetch_add |
C11 |
原子加法 |
atomic_fetch_sub |
C11 |
原子减法 |
atomic_fetch_or |
C11 |
原子地按位或 |
atomic_fetch_xor |
C11 |
原子地按位异或 |
atomic_fetch_and |
C11 |
原子地按位且 |
atomic_flag_test_and_set |
C11 |
原子地将 atomic_flag 设为 true 并返回旧值 |
atomic_flag_clear |
C11 |
原子地将 atomic_flag 设为 false |
| 指定内存顺序的原子操作 |
标准 |
说明 |
atomic_store_explicit |
C11 |
原子地将值存入对象 |
atomic_load_explicit |
C11 |
原子地读取对象 |
atomic_exchange_explicit |
C11 |
原子地将值与对象交换 |
atomic_compare_exchange_weak_explicit |
C11 |
原子地将值 A 与对象比较,如果相等则将值 B 与对象交换,可能虚假地失败,速度更快,常用于循环中 |
atomic_compare_exchange_strong_explicit |
C11 |
原子地将值 A 与对象比较,如果相等则将值 B 与对象交换 |
atomic_fetch_add_explicit |
C11 |
原子加法 |
atomic_fetch_sub_explicit |
C11 |
原子减法 |
atomic_fetch_or_explicit |
C11 |
原子地按位或 |
atomic_fetch_xor_explicit |
C11 |
原子地按位异或 |
atomic_fetch_and_explicit |
C11 |
原子地按位且 |
atomic_flag_test_and_set_explicit |
C11 |
原子地将 atomic_flag 设为 true 并返回旧值 |
atomic_flag_clear_explicit |
C11 |
原子地将 atomic_flag 设为 false |
# 内存顺序
内存顺序指定了原子操作如何影响其他线程的内存访问顺序。
| 内存顺序 |
标准 |
说明 |
memory_order_relaxed |
C11 |
仅保证本次操作的原子性,对其它内存操作没有约束 |
memory_order_consume |
C11(在 C++ 26 废弃) |
仅保证数据依赖的顺序;通常退化为 memory_order_acquire |
memory_order_acquire |
C11 |
保证读取当前原子变量之后的操作不会被重排到前面 |
memory_order_release |
C11 |
保证写入当前原子变量之前的操作不会被重排到后面 |
memory_order_acq_rel |
C11 |
组合 memory_order_acquire 和 memory_order_release |
memory_order_seq_cst |
C11 |
一切按顺序执行,通常最慢,但最简单安全 |
# 推荐阅读
本文 更新于: 2025-11-27 09:38:07 创建于: 2025-11-27 09:38:07