std::atomic 原子操作
std::atomic提供无锁的线程安全操作,比互斥锁快 10-100x,是高性能并发的基础工具。
基本原子类型
cpp
#include <atomic>
// 常用原子类型
std::atomic<int> ai{0};
std::atomic<bool> ab{false};
std::atomic<uint64_t> au{0};
std::atomic<float> af{0.0f}; // C++20 支持浮点原子操作
std::atomic<void*> ap{nullptr};
// 原子操作
ai.store(42); // 写
int val = ai.load(); // 读
int old = ai.exchange(99); // 交换,返回旧值
// 比较并交换(CAS)— 无锁算法的核心
int expected = 42;
bool ok = ai.compare_exchange_strong(expected, 100);
// 如果 ai == expected,则 ai = 100,返回 true
// 否则 expected = ai 的当前值,返回 false
// 算术操作(整数类型)
ai.fetch_add(1); // ai += 1,返回旧值
ai.fetch_sub(1); // ai -= 1,返回旧值
ai++; // 等价于 fetch_add(1)
++ai;
// 位操作
ai.fetch_and(0xFF);
ai.fetch_or(0x01);
ai.fetch_xor(0x0F);内存序
cpp
// 六种内存序(从弱到强)
std::atomic<int> x{0};
// relaxed:只保证原子性,不保证顺序(最快)
x.store(1, std::memory_order_relaxed);
x.load(std::memory_order_relaxed);
// release/acquire:建立 happens-before 关系(常用)
x.store(1, std::memory_order_release); // 发布:之前的写对 acquire 可见
x.load(std::memory_order_acquire); // 获取:之后的读能看到 release 之前的写
// acq_rel:同时具备 acquire 和 release(用于 RMW 操作)
x.fetch_add(1, std::memory_order_acq_rel);
// seq_cst:顺序一致性(默认,最强,最慢)
x.store(1, std::memory_order_seq_cst);
x.load(std::memory_order_seq_cst);
// 实际使用建议:
// 计数器、统计:relaxed
// 生产者-消费者标志:release/acquire
// 不确定时:seq_cst(默认)无锁数据结构
cpp
// 无锁栈(Treiber Stack)
template<typename T>
class LockFreeStack {
struct Node {
T data;
Node* next;
Node(T d) : data(std::move(d)), next(nullptr) {}
};
std::atomic<Node*> head_{nullptr};
public:
void push(T val) {
auto* node = new Node(std::move(val));
node->next = head_.load(std::memory_order_relaxed);
// CAS 循环:直到成功
while (!head_.compare_exchange_weak(
node->next, node,
std::memory_order_release,
std::memory_order_relaxed));
}
std::optional<T> pop() {
Node* old_head = head_.load(std::memory_order_relaxed);
while (old_head) {
if (head_.compare_exchange_weak(
old_head, old_head->next,
std::memory_order_acquire,
std::memory_order_relaxed)) {
T val = std::move(old_head->data);
delete old_head; // 注意:ABA 问题!生产代码需要 hazard pointer
return val;
}
}
return std::nullopt;
}
};原子标志(std::atomic_flag)
cpp
// atomic_flag 是最简单的原子类型,保证无锁
std::atomic_flag flag = ATOMIC_FLAG_INIT;
// 自旋锁实现
class SpinLock {
std::atomic_flag flag_ = ATOMIC_FLAG_INIT;
public:
void lock() {
while (flag_.test_and_set(std::memory_order_acquire)) {
// 自旋等待(可以加 CPU 暂停提示)
#if defined(__x86_64__)
__builtin_ia32_pause(); // x86 PAUSE 指令,减少功耗
#endif
}
}
void unlock() {
flag_.clear(std::memory_order_release);
}
};
// C++20 新增 test() 方法
std::atomic_flag ready = ATOMIC_FLAG_INIT;
// 线程 1
ready.test_and_set();
ready.notify_one(); // C++20:通知等待的线程
// 线程 2
ready.wait(false); // C++20:等待直到值变为 true实用模式
cpp
// 模式 1:引用计数(shared_ptr 的核心)
std::atomic<int> ref_count{1};
void add_ref() { ref_count.fetch_add(1, std::memory_order_relaxed); }
void release() {
if (ref_count.fetch_sub(1, std::memory_order_acq_rel) == 1) {
// 最后一个引用,可以销毁
destroy();
}
}
// 模式 2:单次初始化(double-checked locking)
std::atomic<bool> initialized{false};
std::mutex init_mtx;
ExpensiveObject* instance = nullptr;
ExpensiveObject* get_instance() {
if (!initialized.load(std::memory_order_acquire)) {
std::lock_guard lock(init_mtx);
if (!initialized.load(std::memory_order_relaxed)) {
instance = new ExpensiveObject();
initialized.store(true, std::memory_order_release);
}
}
return instance;
}
// 更简单:std::call_once
#include <mutex>
std::once_flag once;
std::call_once(once, []{ instance = new ExpensiveObject(); });
// 模式 3:进度计数器(多线程统计)
std::atomic<uint64_t> processed{0};
std::atomic<uint64_t> errors{0};
void worker() {
// 处理任务...
processed.fetch_add(1, std::memory_order_relaxed);
}
// 主线程定期读取(relaxed 即可,不需要精确同步)
std::cout << "已处理: " << processed.load(std::memory_order_relaxed) << "\n";关键认知
std::atomic 的默认内存序是 seq_cst(最强),性能敏感时根据需求降级。计数器用 relaxed,生产者-消费者用 release/acquire。compare_exchange_weak 在循环中比 strong 更高效(允许伪失败)。