C++内存序场景下单次acquire加载能否与多个release存储同步?
结论
你提到的表述不成立,线程C没有保证一定能看到线程A或B的所有内存写入。
规则解释
你引用的内存序规则存在一个容易被忽略的前提:memory_order_release 存储和 memory_order_acquire 加载要建立同步关系,必须满足acquire操作读取到了对应release操作写入的值,并非只要对同一原子变量分别执行了release和acquire操作就会自动建立同步。
对应你给出的三步执行逻辑,可能出现三类情况:
- 如果线程C的acquire加载读取到的是线程A写入的值:仅A和C建立同步,C能看到A在release存储之前的所有写入,但完全不保证能看到B的任何写入
- 如果线程C的acquire加载读取到的是线程B写入的值:仅B和C建立同步,C能看到B在release存储之前的所有写入,但因为B和A之间没有任何同步操作,C完全不保证能看到A的写入
- 如果线程C的acquire加载读取到的是
v的初始值:此时和A、B都没有建立同步,完全不保证能看到A或B的任何写入
标准依据补充
你问的“acquire仅匹配对应release”的规则在C++标准[atomics.order]章节有明确约定:
对于使用
memory_order_acquire的原子加载操作L,和使用memory_order_release的原子存储操作S,当且仅当L读取到S写入的值,或读取到S领头的释放序列中任意操作写入的值时,S和L之间建立synchronizes-with同步关系。
而释放序列的定义也明确排除了你场景中B的操作:释放序列指同一原子变量上,由release操作领头的操作序列,后续操作要么是领头操作所在线程的写操作,要么是原子读-修改-写操作。你场景中的B是其他线程执行的独立存储操作,不属于A的释放序列,因此C就算读到B的值,也和A没有任何同步关联。
内容的提问来源于stack exchange,提问作者Koosha
相关产品推荐
相关产品推荐

