不会。std::atomic::exchange 是无锁原子操作,编译为单条CPU指令(如xchg),不阻塞线程、不引发调度切换;仅当非lock-free时可能退化为内部加锁,但基础类型在主流平台均满足lock-free。

std::atomic::exchange 会阻塞线程吗?
不会。exchange 是一个无锁(lock-free)原子操作,底层通常编译为单条 CPU 指令(如 x86 的 xchg 或 mov+lock 前缀),不涉及互斥量或系统调用,因此不会导致线程挂起或调度切换。
但要注意:如果目标 std::atomic 对象不是 lock-free(可通过 is_lock_free() 检查),则可能退化为内部加锁实现——此时虽仍保证原子性,但存在极小概率的争用开销。绝大多数基础类型(int、bool、指针)在主流平台都是 lock-free 的。
exchange 和 store + load 有什么本质区别?
exchange 是读-改-写(RMW)的原子整体,不可分割;而手动 store + load 是两个独立操作,中间可能被其他线程插入修改,无法保证“获取旧值并设新值”这一逻辑的原子性。
常见错误场景:
立即学习“C++免费学习笔记(深入)”;
组合式C++代码评审方案,融合静态分析、AI推理、多轮迭代评审和C++专项检查,适用于PR审查、增量代码审查、全项目评审和代码质量评分,触发词包括review cpp、cpp代码评审、C++review、代码审查。
- 用
old = atomic.load(); atomic.store(new_val);替代old = atomic.exchange(new_val);—— 这会导致竞态:两次操作之间,别的线程可能已把值改回原样或改成别的值 - 误以为
exchange等价于compare_exchange_strong的简化版 —— 实际上它不检查旧值,无条件覆盖,也不返回是否成功(总是成功)
如何正确使用 exchange 的 memory_order 参数?
exchange 默认使用 memory_order_seq_cst(顺序一致性),最安全但也略重;若明确知道上下文约束,可降级以提升性能:
- 仅用于线程间传递信号(如状态标志翻转),且无需与其他内存访问同步 → 可用
memory_order_relaxed - 需确保当前写对其他线程的后续读可见(如发布初始化数据后置 flag)→ 用
memory_order_release(配合另一端的memory_order_acquire) - 不要随意用
memory_order_consume:实际支持有限,易出错,一般不推荐
示例:
std::atomic<int> counter{0};
int old = counter.exchange(42, std::memory_order_acq_rel); // 读写都带屏障,适合计数器重置
exchange 能用于指针和自定义类型吗?
可以用于指针(std::atomic<T*>),但不能直接用于任意自定义结构体——除非该类型满足 trivially copyable 且 sizeof ≤ 平台最大原子宽度(通常 ≤ 16 字节),且编译器确认 lock-free(可用 is_always_lock_free 静态断言)。
典型安全用法:
-
std::atomic<int*>:安全,常用于无锁栈/队列的 head 指针更新 -
std::atomic<std::shared_ptr<T>>:C++20 起支持,内部用控制块指针原子交换 -
struct { int a; char b; };:可能不满足对齐或大小要求,exchange编译失败或 fallback 到锁实现
务必在使用前验证:static_assert(decltype(my_atomic)::is_always_lock_free);

















