memory_order_relaxed是否遵循同一线程内的数据依赖规则?
std::atomic<uint64_t> x; uint64_t f() { x.store(20, std::memory_order::memory_order_relaxed); x.store(10, std::memory_order::memory_order_relaxed); return x.load(std::memory_order::memory_order_relaxed); }
结论
函数f不可能返回10以外的值,你担心的同一线程内数据依赖被忽略的情况不会发生。
C++标准的内存模型对所有内存序都有基础约束:同一线程内按程序顺序排列的操作,其先后关系和可见性不受内存序选择的影响,即便是最宽松的std::memory_order_relaxed也不例外。
std::memory_order_relaxed的唯一作用是取消跨线程的同步/顺序约束:它仅保证操作本身的原子性,不需要和其他线程的原子操作做同步对齐。但对于单线程内部对同一个原子变量的访问,规则和非原子变量完全一致:
- 先执行的
store(20)一定发生在store(10)之前 store(10)一定发生在后续的load之前- 后执行的写操作一定会覆盖之前的写入值,后续读操作必然读到最后一次写入的10
编译器和CPU都不会对同一线程内访问同一变量的操作做会改变执行结果的重排,哪怕使用relaxed内存序也不允许。你担心的顺序混乱只会出现在多线程场景下:比如其他线程同时读取x时,可能观察到x的值是初始值、20或者10,但这不会影响执行f的线程本身的执行结果。
内容的提问来源于stack exchange,提问作者Joseph Garvin
相关产品推荐
相关产品推荐

