直接回答:Ordering 控制原子操作与周围内存访问之间允许的重排程度。Relaxed 只保证操作本身原子,不建立任何顺序;Acquire(读)/Release(写)配对建立 happens-before——store(Release) 之前的所有写,对随后 load(Acquire) 读到该值的线程可见;SeqCst 要求所有 SeqCst 操作存在全局唯一全序,最易推理但开销最大。
展开解析:典型用法:Relaxed 用于计数器,只关心总数、不关心与其他数据的先后;Acquire/Release 用于“发布”模式——先写数据,再 store(flag, Release),对方 load(flag, Acquire) 为真即可安全读数据,自旋锁、一次性初始化都基于此;AcqRel 用于 fetch_add 这类读-改-写。x86 上 Acquire load 几乎免费,SeqCst store 才需额外指令;ARM 各档都要插 barrier。实践上先用 SeqCst 保证正确再逐点降阶;弱序 bug 难复现,可用 loom 做穷举检验。
DATA.store(42, Ordering::Relaxed);
READY.store(true, Ordering::Release); // 之前的写先于它可见
if READY.load(Ordering::Acquire) {
assert_eq!(DATA.load(Ordering::Relaxed), 42); // 保证成立
}
追问方向:为什么 x86 上 Acquire load 几乎免费?fence 与操作上的 Ordering 区别?compare_exchange 为何分开指定成功/失败 Ordering?
(约 630 字)