使用std::memory_order_relaxed是否会引发无限循环?相关疑问咨询
关于原子操作内存顺序与线程重排的问题分析
先贴出你提供的问题代码:
#include <atomic> #include <thread> std::atomic_bool stop(false); void wait_on_stop() { while (!stop.load(std::memory_order_relaxed)); } int main() { std::thread t(wait_on_stop); stop.store(true, std::memory_order_relaxed); t.join(); }
你的推理是否正确?
完全正确。
std::memory_order_relaxed是最宽松的内存顺序规则,它只保证原子操作本身的原子性,不提供任何跨线程的同步约束,也不限制编译器或CPU对操作的重排序。在main函数中,stop.store(true, std::memory_order_relaxed)和t.join()这两个操作之间没有强制的顺序依赖(从relaxed的规则角度看),所以编译器完全有权限把store指令重排到join之后执行。
这种情况下,线程t会一直卡在while (!stop.load(...))的循环里——因为stop的值始终是false,而main里的store操作要等到join返回后才会执行,这就形成了死锁,t.join()永远无法返回。
改成stop.store(true)能否解决问题?
可以解决。
std::atomic::store的默认内存顺序是std::memory_order_seq_cst,这是最严格的内存顺序约束:
- 它会禁止编译器和CPU将这个store操作与后续的
t.join()进行重排序,确保stop的赋值操作一定在等待线程结束之前完成; - 同时,
seq_cst的写操作会确保所有线程最终都能看到这个更新后的值(即使线程t里的load用的是memory_order_relaxed,原子操作本身的原子性加上seq_cst的全局顺序保证,循环中的load最终会读取到true,从而退出循环)。
这样就能彻底避免死锁,让程序正常结束。
内容的提问来源于stack exchange,提问作者Lingxi
相关产品推荐
相关产品推荐

