多读取线程能否通过acquire/release序与同一写入线程同步?
问题结论
两个reader线程的assert都不可能触发失败,你的代码在C++标准内存模型下是完全安全的。
规则依据
C++标准对release-acquire内存序的同步规则明确规定:
- 如果一个原子变量的
memory_order_release存储操作,被任意线程的memory_order_acquire加载操作读到了写入值,那么存储操作之前的所有内存写入,都对该加载操作所在的线程完全可见。 - 这条规则对所有读到该release存储值的acquire操作都生效,不存在“仅能配对一个acquire操作”的限制,多读者场景下每个符合条件的acquire操作都会独立建立同步关系。
对应你的代码场景
- writer线程中
i = 42的普通写入,先行发生于b.store(true, memory_order_release)操作 - 不管是t2还是t3,只要
b.load(memory_order_acquire)返回true,就说明读到了writer线程写入的true值,此时和writer的release操作建立了同步关系 - 因此writer线程中
i = 42的写入对reader线程可见,assert(i == 42)必然成立
int i{}; atomic<bool> b{}; void writer(){ i=42; b.store(true,memory_order_release); } void reader(){ while(!b.load(memory_order_acquire)) this_thread::yield(); assert(i==42); } //--------------------- thread t1{writer},t2{reader},t3{reader};
常见误区说明
不要误以为release存储的同步关系只能绑定第一个acquire加载,标准没有这种限制,只要acquire读操作拿到了release写的值,就能拿到所有前置副作用,不管有多少个读线程执行了这个acquire操作。
内容的提问来源于stack exchange,提问作者Despise
相关产品推荐
相关产品推荐

