std::atomic提供原子操作确保多线程安全,通过硬件指令实现无锁并发,支持内存序控制可见性与顺序,适用于计数、标志位等场景。

std::atomic 是 C++11 引入的一个模板类,用于提供对单一变量的原子操作,从而确保在多线程环境下对该变量的读写是线程安全的。它通过底层硬件支持和编译器指令来避免数据竞争,不需要显式使用互斥锁(mutex)。
原子操作的基本原理
原子操作意味着该操作在执行过程中不会被线程调度机制打断。其他线程要么看到操作完成前的状态,要么看到操作完成后的状态,不存在中间状态。
std::atomic 对常见类型(如 int、bool、指针等)封装了原子读、写、增、减、比较并交换等操作,例如:
- load():原子地读取值
- store(val):原子地写入值
- fetch_add()、operator++:原子增加
- compare_exchange_weak()、compare_exchange_strong():比较并交换(CAS)
这些操作在底层通常由 CPU 提供的原子指令实现,比如 x86 架构中的 LOCK 前缀指令或 CMPXCHG 指令。
立即学习“C++免费学习笔记(深入)”;
内存序(Memory Order)控制可见性与顺序
std::atomic 允许指定内存序,以控制操作的同步行为和性能。不同的内存序影响编译器优化和 CPU 乱序执行的程度。
常用内存序包括:
- memory_order_relaxed:仅保证原子性,不保证顺序(适合计数器)
- memory_order_acquire / release:用于线程间同步,确保读写顺序
- memory_order_seq_cst:默认最严格,保证全局顺序一致性
例如,一个线程写入数据并用 release 存储标志,另一个线程用 acquire 加载该标志,就能安全读取之前写入的数据。
底层实现依赖硬件与编译器
std::atomic 的线程安全性依赖于:
- CPU 的原子指令支持(如 x86 的 LOCK 前缀、ARM 的 LDREX/STREX)
- 编译器生成正确的汇编代码,并插入必要的内存屏障(fence)
- 对齐和类型限制:某些类型必须正确对齐才能原子操作(如 64 位类型在 32 位系统上可能不支持原子性)
如果类型不支持无锁实现,std::atomic 会内部使用互斥锁模拟原子操作(可通过 is_lock_free() 查询)。
典型应用场景
适用于需要高效共享状态而无需锁的场景:
- 引用计数(如 shared_ptr)
- 标志位控制(如退出标志)
- 无锁队列或数据结构中的节点指针操作
示例:
std::atomicready{false}; std::atomic data{0}; // 线程1 data.store(42); ready.store(true);
// 线程2 while (!ready.load()) { / 等待 / } int val = data.load(); // 安全读取
基本上就这些。std::atomic 通过封装底层原子指令和内存序语义,在语言层面提供了高效且可移植的线程安全保障。关键在于理解其操作的原子性和内存可见性规则,避免误用导致逻辑错误。











