std::atomic是c++中用于保证共享变量操作原子性的模板类,定义在<atomic>头文件中,支持int、bool、指针等平凡可复制类型,通过load、store、exchange和compare_exchange_weak/strong等成员函数实现线程安全的读取、写入和比较交换操作,避免数据竞争;其操作可指定内存序(如memory_order_relaxed、acquire/release、seq_cst),其中seq_cst为默认且最严格;常用于实现无锁编程,但不支持拷贝构造与赋值,复杂同步仍需配合互斥锁使用。

在C++多线程编程中,std::atomic 是用于实现原子操作的核心工具。它确保对共享数据的读取、修改和写入操作不会被多个线程同时干扰,从而避免数据竞争(data race),保证并发安全。
什么是 std::atomic?
std::atomic 是一个模板类,定义在 <atomic> 头文件中,用于封装某种类型的变量(如 int、bool、指针等),使其操作具有原子性。这意味着在多线程环境下,对该变量的操作是不可分割的——不会出现中间状态被其他线程观察到的情况。
常见的原子类型包括:
- std::atomic<int>
- std::atomic<bool>
- std::atomic<T*>(用于原子指针)
- C++17 起还提供了 std::atomic_flag(最轻量的原子布尔标志)
为什么需要原子操作?
在没有原子操作的情况下,多个线程对同一变量进行递增操作可能会导致结果错误。例如:
立即学习“C++免费学习笔记(深入)”;
int counter = 0; // 多个线程执行 counter++;
看似简单的操作实际上包含“读-改-写”三个步骤,在并发场景下可能交错执行,最终结果小于预期。
使用 std::atomic 可以解决这个问题:
#include <atomic> #include <thread> #include <vector> std::atomic<int> counter(0); void increment() { for (int i = 0; i < 1000; ++i) { counter++; // 原子递增,线程安全 } } int main() { std::vector<std::thread> threads; for (int i = 0; i < 10; ++i) { threads.emplace_back(increment); } for (auto& t : threads) { t.join(); } // 最终 counter 的值一定是 10000 return 0; }
常用原子操作与内存序
std::atomic 提供了多种成员函数来执行不同语义的原子操作:
- load():原子地读取值
- store(val):原子地写入值
- exchange(val):设置新值并返回旧值
- compare_exchange_weak() 和 compare_exchange_strong():比较并交换(CAS),是实现无锁算法的基础
这些操作可以接受一个可选的内存序(memory order)参数,控制操作的内存同步行为。常用的有:
- std::memory_order_relaxed:最宽松,仅保证原子性,不保证顺序
- std::memory_order_acquire / release:用于实现锁或同步点
- std::memory_order_seq_cst:默认选项,提供最严格的顺序一致性,安全性最高但性能略低
示例:使用 compare_exchange_strong 实现线程安全的单例或无锁栈节点插入:
std::atomic<int> value(0); int expected = value.load(); while (!value.compare_exchange_strong(expected, 42)) { // 如果当前值等于 expected,则设为 42;否则更新 expected 为当前值 // 循环重试直到成功 }
注意事项与限制
并非所有类型都能用于 std::atomic。只有满足“平凡可复制(trivially copyable)”的类型才支持。例如自定义结构体需谨慎使用,通常建议只用于基本类型或指针。
另外,虽然原子操作避免了数据竞争,但并不意味着完全不需要互斥锁。复杂逻辑或多变量协调仍可能需要 mutex 配合。
std::atomic 不支持拷贝构造和赋值,因为这会破坏原子性保障。
基本上就这些。std::atomic 是编写高效并发程序的重要工具,理解其原理和用法有助于写出更安全、更高性能的多线程代码。关键是掌握 load/store、CAS 操作以及合理选择内存序。


