跳到主要内容
版本:1.0

atomic

std::atomic 是 C++11 引入的原子操作模板,保证对单个变量的读写和修改操作在多线程环境下是原子的,不会出现数据竞争。它比 mutex 更轻量,适合保护单个标志位、计数器等简单共享变量。

头文件与基本特征

#include <atomic>
特征说明
角色对单个变量提供原子访问
锁开销通常无锁(lock-free),由硬件原子指令实现
适用场景标志位、引用计数、自旋锁等简单同步
不适用保护多个变量的一致性(用 mutex

基本用法

#include <atomic>
#include <iostream>
#include <thread>

std::atomic<int> counter(0);

void work() {
for (int i = 0; i < 100000; ++i) {
++counter;
}
}

int main() {
std::thread t1(work);
std::thread t2(work);
t1.join();
t2.join();
std::cout << counter.load() << '\n'; // 200000
return 0;
}

++counter 是原子的,无需加锁,两个线程不会产生数据竞争。

常用操作

操作作用
load()读取当前值
store(x)写入值
exchange(x)写入新值并返回旧值
compare_exchange_weak(expected, desired)CAS,值匹配时替换
compare_exchange_strong(expected, desired)CAS 的强一致版本
fetch_add(n) / fetch_sub(n)原子加减,返回旧值
operator++ / operator--原子自增/自减
operator+= / operator-=原子复合赋值

常用场景

标志位

std::atomic<bool> ready(false);

// 线程 A:
ready.store(true);

// 线程 B:
while (!ready.load()) {
// 等待
}

自旋锁

std::atomic_flag lock = ATOMIC_FLAG_INIT;

void critical() {
while (lock.test_and_set()) {
// 自旋等待
}
// 临界区
lock.clear();
}

atomic vs mutex

场景推荐
单个计数器/标志位atomic
保护多个变量的一致性mutex
临界区包含多行逻辑mutex
需要和条件变量配合mutex

使用注意

  1. atomic 只保护单个原子操作,两个连续的原子操作之间仍可能被切换。
  2. 不是所有类型都无锁,用 is_lock_free() 可以检查。
  3. compare_exchange_weak 可能伪失败,需要在循环中使用。
  4. 复杂数据结构不能用 atomic 保护,必须用 mutex

小结

std::atomic 是最轻量的并发同步方式,适合标志位、计数器和简单自旋等待。它比 mutex 更快但功能更窄,二者配合 condition_variable 构成了 C++11 并发编程的三大基石。