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

C++顺序一致性是否保证读取内存最新值?技术问询

C++顺序一致性内存序下的原子操作困惑解析

首先看示例代码:

std::atomic<int> X(0), Y(0);
int r1, r2;

void thread1()
{
    X.store(1); // 默认使用std::memory_order_seq_cst
    r1 = Y.load(); // 默认使用std::memory_order_seq_cst
}

void thread2()
{
    Y.store(1); // 默认使用std::memory_order_seq_cst
    r2 = X.load(); // 默认使用std::memory_order_seq_cst
}

核心问题拆解

  1. 顺序一致性的核心规则:std::memory_order_seq_cst要求所有原子操作存在一个全局总序,且这个总序与每个线程内部的程序顺序完全一致——线程内先执行的操作,在全局总序里必然排在后执行的操作前面。
  2. 断言触发可能性:assert(r1 != 0 && r2 != 0)是可能触发的,但绝对不会出现r1=0且r2=0的情况:
    • 比如全局总序为:thread1的X.store → thread1的Y.load → thread2的Y.store → thread2的X.load,此时r1=0(thread1读取Y时,thread2的Y.store还未执行),r2=1(thread2读取X时,thread1的X.store已完成),断言会触发。
    • 反过来,若全局总序是thread2的Y.store → thread2的X.load → thread1的X.store → thread1的Y.load,则r2=0,r1=1,断言同样会触发。
    • 不存在能让r1=0且r2=0的全局总序:如果r1=0,说明thread2的Y.store在thread1的Y.load之后,而thread2的程序顺序要求Y.store在X.load之前,因此thread2的X.load必然在thread1的Y.load之后;又因为thread1的X.store在Y.load之前,所以thread1的X.store一定在thread2的X.load之前,此时thread2的X.load必须读到1,即r2=1。同理,若r2=0则r1必为1。

Preshing与Anthony Williams的说法并不矛盾

  • Preshing的表述应该是指不会出现r1和r2同时为0的情况,这完全符合顺序一致性的规则。
  • Anthony Williams提到的“仍可能读到旧值”,指的是单个线程可能读到另一线程后续才完成的存储操作的旧值(比如上述例子中r1=0或r2=0的情况),这也完全正确——顺序一致性只保证全局总序的存在,不保证跨线程操作一定能彼此看见,只是约束了可见性的逻辑边界。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.16 22:01:19