std::atomic 和 std::atomic 初始化需显式设为 nullptr,否则值未定义;前者支持指针算术,后者不支持;两者均要求 t 为平凡可复制类型,且仅保证指针原子性,不保护所指对象。

std::atomic 和 std::atomic 的初始化差异
直接用 std::atomic<int></int> 是合法的,但 std::atomic<void></void> 更常用于泛型指针操作;两者都要求指针类型是平凡可复制的(trivially copyable),所以不能包装含虚函数或非平凡构造/析构的类指针。
常见错误是未显式初始化:
-
std::atomic<int> ptr;</int>—— 值未定义,后续load()可能读到垃圾地址 -
std::atomic<int> ptr{nullptr};</int>或std::atomic<int> ptr = nullptr;</int>—— 安全起点 - 不能写
std::atomic<int> ptr = new int(42);</int>,因为new表达式不是常量表达式,需用store()后赋值
原子指针的 load/store 与内存序控制
指针的原子读写默认使用 std::memory_order_seq_cst,但多数场景下可以放宽——尤其在单生产者/单消费者队列中,load() 用 std::memory_order_acquire、store() 用 std::memory_order_release 就够了,性能更好且语义清晰。
示例:安全发布一个新节点
struct Node {
int data;
Node* next;
};
std::atomic<node> head{nullptr};
<p>void push(Node* new_node) {
new_node->next = head.load(std::memory_order_acquire);
// 确保 new_node->next 已读取完毕,再写 head
head.store(new_node, std::memory_order_release);
}</p></node>
注意:head.load() 不加参数等价于 head.load(std::memory_order_seq_cst),但这里用 acquire 更贴合“读取旧头”的语义。
compare_exchange_weak 在链表 CAS 更新中的典型用法
无锁链表插入必须用 CAS 循环,因为 compare_exchange_weak 可能虚假失败(spurious failure),尤其在 ARM 或某些编译器优化下。不能只试一次就放弃。
组合式C++代码评审方案,融合静态分析、AI推理、多轮迭代评审和C++专项检查,适用于PR审查、增量代码审查、全项目评审和代码质量评分,触发词包括review cpp、cpp代码评审、C++review、代码审查。
关键点:
-
expected必须是变量(不能是字面量或临时量),因为失败时它会被更新为当前值 - 循环内要重新计算
desired,比如插入前需重读next字段 - 对指针做 CAS 时,比较的是地址值,不是所指对象内容
示例:
Node* expected = head.load();
Node* desired;
do {
new_node->next = expected;
desired = new_node;
} while (!head.compare_exchange_weak(expected, desired));
如果 head 在读取后被其他线程改过,expected 就不匹配,循环重试。
std::atomic 支持指针算术,但 std::atomic 不支持
std::atomic<int></int> 允许 fetch_add(1)、++ptr 这类操作,底层按 sizeof(int) 偏移;而 std::atomic<void></void> 不支持,编译报错——因为 void 无大小,无法确定步长。
所以:
- 需要指针遍历(如数组索引)→ 用
std::atomic<t></t>,比如std::atomic<int></int> - 仅需存储/交换任意地址(如句柄、opaque 指针)→ 用
std::atomic<void></void>,更通用但功能受限 - 别试图对
std::atomic<void></void>调用fetch_add,错误信息通常是"no member named 'fetch_add' in 'std::atomic<void>'"</void>
最后提醒:原子指针只保证指针本身的读写是原子的,不保护它指向的对象。若要线程安全访问 *ptr,仍需额外同步机制(如互斥锁或对象自身也是原子封装)。
C++免费学习笔记(深入):立即使用
在学习笔记中,你将探索 C++ 的入门与实战技巧!










