原子操作是C++多线程中保障单变量原子性读写的机制,通过std::atomic实现无锁线程安全;支持隐式/显式内存序、compare_exchange及atomic_flag等,但不适用于多变量协同或浮点复合运算。

原子操作是C++多线程编程中保证变量读写不被中断、避免数据竞争的核心机制。用好std::atomic,不需要锁也能实现线程安全的简单共享变量访问。
基础用法:声明和初始化
把普通类型换成对应原子类型即可,比如int → std::atomic_int,或更通用的std::atomic:
-
std::atomic—— 值初始化为0,支持所有基本整型、指针、以及满足 trivially copyable 的自定义类型(需额外注意对齐和大小限制)counter{0}; - 不能直接用拷贝构造或赋值(如
auto x = counter;会调用隐式转换,实际是load());也不能传给需要非const引用的函数 - 推荐用
std::atomic模板,比内置别名(如atomic_int)更清晰、可移植性更好
读写操作:默认隐式 vs 显式控制内存序
最常用的是隐式操作:counter++、counter.load()、counter.store(42)、counter.exchange(100)。它们默认使用std::memory_order_seq_cst(顺序一致性),最安全也稍慢。
- 若需更高性能且逻辑允许,可显式指定内存序,例如:
counter.fetch_add(1, std::memory_order_relaxed)(仅保证原子性,不约束前后指令重排) - 对计数器、标志位等简单场景,
relaxed常够用;涉及状态协同(如生产者-消费者)时,常用acquire/release - 误用弱内存序可能导致逻辑错误,初学者建议先全用默认,再按需优化
常见组合操作:compare_exchange 和 flag
compare_exchange_weak和compare_exchange_strong是实现无锁结构的基础,用于“比较并交换”:
立即学习“C++免费学习笔记(深入)”;
- 典型模式:
int expected = counter.load(); do { /* 修改expected */ } while (!counter.compare_exchange_weak(expected, new_value)); -
weak可能虚假失败(spuriously fail),适合循环重试;strong不虚假失败,但某些平台开销略大 - 还有轻量级布尔标记:
std::atomic_flag,只支持test_and_set()和clear(),是唯一保证无锁(lock-free)的原子类型,适合实现自旋锁
注意事项和限制
原子类型不是万能锁替代品:
- 仅对单个对象有效;多个相关变量无法靠多个原子操作自动同步(比如x和y要一起更新,就得用mutex或自定义原子结构)
- 不支持浮点类型的
fetch_add等复合操作(C++20起部分编译器扩展支持,但非标准) - 用
is_lock_free()检查是否真正无锁(尤其在结构体上),否则底层可能用互斥量模拟,失去性能优势 - 避免在原子变量上取地址(
&counter非法),也不支持sizeof以外的指针运算
基本上就这些。用对场景、选对内存序、避开多变量耦合——原子操作就能既安全又高效。









