You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

C++11顺序一致性内存序是否禁止存储缓冲区Litmus测试出现r1、r2均为0的结果?

// 初始状态
std::atomic<int> x(0), y(0);

// 线程1                // 线程2
x.store(1);           y.store(1);
auto r1 = y.load();   auto r2 = x.load();

结论

在所有操作均使用memory_order_seq_cst(std::atomic默认内存序)的前提下,不可能出现r1和r2同时为0的情况,该结果是被C++内存模型明确禁止的。


规则推导过程

你提到的memory_order_seq_cst的全局全序规则,刚好就是禁止这个结果的核心约束:
所有标记为memory_order_seq_cst的操作,必须存在一个所有线程都观测一致的全局总执行顺序,我们可以基于这个总序做推导:
两个写操作x.store(1)(记为Sx)和y.store(1)(记为Sy)在全局总序里必然有先后关系,只会出现两种可能:

  1. 全局总序中Sx执行在Sy之前:
    线程2的执行顺序是先执行Sy,再执行x.load()(记为Lx),因此Lx在全局总序中的位置一定晚于Sy,也就晚于Sx。SC加载要求能看到全局总序中排在它之前的所有对该变量的修改,因此Lx必然读到x=1,r2不可能为0。
  2. 全局总序中Sy执行在Sx之前:
    同理,线程1的y.load()(记为Ly)在全局总序中的位置晚于Sx,也就晚于Sy,因此Ly必然读到y=1,r1不可能为0。

两种场景下都不可能出现r1、r2同时为0的结果,所以该结果被明确禁止。


补充说明

如果把操作的内存序换成memory_order_release(存储)+memory_order_acquire(加载),那么r1和r2同时为0的结果是被允许的。因为acquire-release语义没有要求不同线程对无关变量的写操作存在全局一致的顺序,两个线程的写操作可以都晚于对方的读操作,从而出现都读到初始值0的情况,这也正是memory_order_seq_cst和acquire-release语义的核心差异之一。

内容的提问来源于stack exchange,提问作者zanmato

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.09.24 10:15:03