memory_order 是原子操作的内存序约束,指定读写重排边界,非锁亦非同步点;需成对使用 acquire-release 等组合建立 happens-before,单侧设置无效。
memory_order 是什么,不是什么
memory_order 不是锁,也不是同步点本身,它只是告诉编译器和 CPU:“这条原子操作的读写,**在什么范围内允许重排**”。它不保证其他非原子变量的可见性,也不自动建立 happens-before 关系——必须成对使用(比如一个 store 配一个 load),且顺序要匹配,否则屏障无效。
常见误用:只在单侧加 memory_order_acquire,另一侧仍是默认 memory_order_seq_cst 或更弱,结果依赖关系断裂,读到陈旧值。
最常用四组 memory_order 组合的实际效果
真正影响执行行为的是「成对操作」的约束组合,不是单个枚举值:
-
memory_order_relaxed:仅保证原子性,不参与同步。适合计数器、引用计数递增等无需顺序语义的场景 -
memory_order_acquire+memory_order_release:构成“获取-释放”同步。写端用release,读端用acquire,可让该原子操作之前/之后的内存访问分别不被重排到其后/前——这是实现无锁队列、双检查锁(DCLP)的关键 -
memory_order_acquire+memory_order_consume:已基本弃用(C++20 中标记为 deprecated),因数据依赖链难以静态分析,编译器难优化,且多数架构上与acquire等价 -
memory_order_seq_cst:全局顺序一致。所有线程看到同一套原子操作执行顺序。性能开销最大(尤其在 ARM/PowerPC 上需显式DMB指令),但语义最直观,调试友好
底层汇编和硬件指令怎么对应
不同平台生成的屏障指令差异很大,不能假设 acquire 总是插入 lfence:
立即学习“C++免费学习笔记(深入)”;