std::atomic::exchange 不会阻塞线程,它是无锁原子操作,通常编译为单条cpu指令;但是否真正lock-free取决于类型大小与平台,需用is_always_lock_free检查。

std::atomic::exchange 会阻塞线程吗
不会。std::atomic::exchange 是一个无锁(lock-free)原子操作,底层通常编译为单条 CPU 指令(如 x86 的 xchg 或 lock xchg),不涉及互斥量或系统调用,因此不会引起线程挂起或调度等待。
但要注意:是否真正 lock-free 取决于类型大小和平台对齐。可通过 T::is_always_lock_free 或 atomic_is_lock_free(&a) 检查。例如 std::atomic<:shared_ptr>></:shared_ptr> 在某些 32 位平台可能退化为内部加锁实现,此时虽语义不变,但性能下降且可能隐含轻量级同步开销。
- 对
int、void*、指针类型,主流编译器在 64 位平台基本保证 lock-free - 自定义结构体若超过指针宽度(如 16 字节
struct),即使声明为std::atomic,exchange很可能 fallback 到 mutex 保护,失去无锁优势 - 使用前建议断言:
static_assert(T::is_always_lock_free, "not lock-free!");
exchange 和 compare_exchange_weak/strong 的关键区别
exchange 总是成功替换并返回旧值;而 compare_exchange 系列只在当前值等于预期时才替换,否则仅读取当前值——这是实现自旋锁、无锁栈等算法的基础。
如果你只是想“不管现在是什么,都换成新值”,exchange 更简洁、无循环、无 ABA 风险顾虑;但若需条件性更新(比如“仅当标志为 idle 时才设为 busy”),必须用 compare_exchange_weak。
-
exchange(new_val)返回旧值,语义等价于“读-改-写”三步原子完成 -
compare_exchange_weak(expected, desired)修改expected为实际旧值(失败时),需手动重试循环 - 性能上,
exchange单次调用开销稳定;compare_exchange_weak在无竞争时极快,高竞争时可能多次失败重试
exchange 的内存序参数怎么选
exchange 默认使用 std::memory_order_seq_cst(顺序一致性),最安全但也最重。多数场景可降级以提升性能,但必须匹配使用逻辑。
常见组合:
- 单纯交换状态标志(如开关、标记位)且不依赖其他内存访问顺序 → 可用
std::memory_order_relaxed - 交换后需确保之前所有写入对其他线程可见(如发布初始化好的数据)→ 至少用
std::memory_order_release - 交换前需看到其他线程的最新写入(如检查某个全局配置再切换)→ 需
std::memory_order_acquire - 同时需要 acquire + release 效果(如锁的 unlock 操作)→ 用
std::memory_order_acq_rel
示例:
std::atomic<bool> ready{false};
// 发布就绪信号:写入其他数据后,用 release 保证它们已刷出
data = compute();
ready.exchange(true, std::memory_order_release); // 其他线程用 acquire 读 ready 才能见到 data</bool>
容易踩的坑:T 类型必须可平凡复制且无副作用
std::atomic<t>::exchange</t> 要求 T 是 trivially copyable,否则编译失败。这意味着不能直接用于 std::string、std::vector 等含动态内存或非平凡析构的类型。
常见误用:
- 试图对
std::atomic<:string></:string>调用exchange→ 编译报错:“user-defined assignment operator not allowed” - 用
std::atomic<:shared_ptr>></:shared_ptr>时忽略引用计数线程安全:exchange 本身原子,但shared_ptr内部引用计数增减仍需原子操作(标准库已保证,无需额外处理) - 跨线程传递指针后,在 exchange 后立刻
delete原指针 → 必须确保没有其他线程还在解引用该指针,原子交换不解决生命周期管理问题
替代方案:对复杂对象,通常用指针包装(std::atomic<t></t>)或配合 std::shared_ptr,由上层逻辑保证对象存活期。
C++免费学习笔记(深入):立即使用
在学习笔记中,你将探索 C++ 的入门与实战技巧!











