std::atomic_flag 是最轻量的无值原子类型,仅支持 test_and_set() 和 clear() 两个操作,必须用 ATOMIC_FLAG_INIT 初始化,适用于自旋锁等底层同步,不可替代 std::atomic。

std::atomic_flag 是 C++ 中最轻量、最底层的原子类型,不带值,只表示“已设置”或“未设置”两种状态,适合实现自旋锁等极简同步原语。
初始化必须用 ATOMIC_FLAG_INIT
它不能用普通方式构造,必须静态或全局初始化(C++17 起支持 constexpr 构造,但仍推荐用 ATOMIC_FLAG_INIT):
错误写法:std::atomic_flag flag; // 未初始化,行为未定义
正确写法:std::atomic_flag flag = ATOMIC_FLAG_INIT; // C++11/14/17 都安全
// 或 C++20 起可写:std::atomic_flag flag{};(默认初始化为 clear)
核心操作只有两个:test_and_set() 和 clear()
它不提供 load/store,也不支持 operator=,只靠这两个函数完成原子切换:
立即学习“C++免费学习笔记(深入)”;
- flag.test_and_set():原子地返回当前状态(false 表示之前是 clear),并立即将 flag 设为 true;默认内存序是 memory_order_seq_cst
- flag.clear():原子地将 flag 设为 false;同样默认用 memory_order_seq_cst
例如实现一个最简自旋锁:
std::atomic_flag lock = ATOMIC_FLAG_INIT;
void critical_section() {
while (lock.test_and_set()) { /* 自旋等待 */ }
// 进入临界区
do_something();
lock.clear(); // 必须释放!否则死锁
}
注意内存序和性能权衡
在无竞争场景下,用 relaxed 内存序可提升性能(但需确保逻辑正确):
- flag.test_and_set(std::memory_order_acquire) —— 获取锁时用 acquire,保证后续读写不被重排到锁前
- flag.clear(std::memory_order_release) —— 释放锁时用 release,保证前面的读写不被重排到锁后
典型搭配是 acquire/release,比默认 seq_cst 更高效,又保持同步语义。
它不是 bool 的原子替代品
别用 atomic_flag 存储业务逻辑的真假值。它没有 load(),不能读状态而不修改;也没有 test()(C++20 新增 test() 成员函数,但仍是实验性扩展,不通用)。需要读-改-写或真值语义,请直接用 std::atomic











