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

为何不同线程可观测不同内存操作顺序?C++并发原子操作疑问

C++原子操作内存序疑惑解答

问题背景

以下是《C++ Concurrency in Action(第二版)》中的示例代码,作者指出线程Tc和Td可能观测到不同的内存状态:

  1. Tc观测到x == true且y == false
  2. Td观测到x == false且y == true
    最终z的值可能为0,触发断言失败。

示例代码

std::atomic<bool> x(false), y(false);
std::atomic<int> z(0);
void write_x() { // Ta
  x.store(true, std::memory_order_release); // A
}
void write_y() { // Tb
 y.store(true, std::memory_order_release);  // B
}
void read_x_then_y() { // Tc
 while(!x.load(std::memory_order_acquire)); // C
 if(y.load(std::memory_order_acquire))      // D
   ++z;
}
void read_y_then_x() { // Td
 while(!y.load(std::memory_order_acquire)); // E
 if(x.load(std::memory_order_acquire))      // F
   ++z;
}
int main() {
 std::thread a(write_x);
 std::thread b(write_y);
 std::thread c(read_x_then_y);
 std::thread d(read_y_then_x);
 a.join();
 b.join();
 c.join();
 d.join();
 assert(z.load() != 0);
}

你最初的理解是:语句A和B的执行顺序要么是AB要么是BA,假设为AB时,Td看到y=true后必然能看到x=true,所以z一定会大于0,但这个理解存在错误。


错误点解析

1. 错误假设了"全局执行顺序"

C++内存模型中不存在全局统一的操作执行顺序,只有线程内部的程序顺序和线程间的同步关系。Ta和Tb是完全独立的线程,它们的store操作之间没有任何同步约束,不存在全局意义上的AB或BA执行顺序。

2. 误解了release-acquire同步的作用范围

std::memory_order_release和std::memory_order_acquire仅能在特定的线程对之间建立同步关系:

  • Ta的x.store(..., release)和Tc的x.load(..., acquire)同步:Tc看到x=true时,能保证看到Ta中所有在该store之前的操作,但这和Tb的操作毫无关联。
  • Tb的y.store(..., release)和Td的y.load(..., acquire)同步:Td看到y=true时,能保证看到Tb中所有在该store之前的操作,但和Ta的操作无关。

Ta和Tb之间没有任何同步机制,所以它们的操作在其他线程的内存视图中可能是乱序的。

3. 导致z=0的具体场景

  • Tc通过while循环看到x=true(确认Ta的store已对自己可见),但此时Tb的y.store操作可能还未对Tc可见,所以Tc执行D时y=false,不会执行++z。
  • Td通过while循环看到y=true(确认Tb的store已对自己可见),但此时Ta的x.store操作可能还未对Td可见,所以Td执行F时x=false,也不会执行++z。
  • 最终z的值为0,触发断言失败。

你之前的错误在于认为"如果A在全局先于B,那么Td看到y=true时必然看到x=true",但全局顺序并不存在,Td看到y=true仅和Tb的操作同步,无法推导出Ta的操作对其可见。


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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.15 16:11:17