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

C/C++不同CPU核心线程是否可能永远看不到共享变量的写入更新?

问题结论

无法保证线程一定能感知到其他线程对共享普通变量的写入,你给出的示例代码中,thread_B完全有可能永远无法停止。

你给出的原始代码如下:

bool stop = false; // 线程A和B共享的全局变量
// 线程A
void thread_A(){
  sleep(10);
  stop = true;
}
// 线程B
void thread_B(){
  while(!stop) {
  // .. 执行业务逻辑
  }
}
具体原因
  • 编译器优化导致可见性失效
    C/C默认按单线程语义做编译优化,编译器不知道stop是跨线程共享的变量,所以在编译thread_B的循环逻辑时,完全可以将!stop的判断优化为:第一次循环时读取内存里的stop值存入寄存器,后续循环直接读寄存器判断,不再重读内存。这种优化完全符合C/C的标准要求,哪怕后续内存里的stop被修改为true,thread_B也永远感知不到。
  • 内存模型层面的未定义行为
    就算手动关闭编译器优化,C++标准也明确规定:没有同步措施的普通跨线程读写属于数据竞争,是未定义行为,哪怕底层CPU实现了缓存一致性协议,也不能保证执行结果符合预期。你提到的写回缓存永远不写回的情况虽然在主流硬件上不会出现,但标准层面根本不保障普通变量的跨线程可见性,出现任何结果都符合标准要求。
修复方案

只需要把共享变量声明为原子变量,即可保证写入的跨线程可见性:

#include <atomic>
std::atomic<bool> stop = false; // 全局共享原子变量
// 线程A
void thread_A(){
  sleep(10);
  // 释放语义写入
  stop.store(true, std::memory_order_release);
}
// 线程B
void thread_B(){
  // 获取语义读取
  while(!stop.load(std::memory_order_acquire)) {
  // .. 执行业务逻辑
  }
}

也可以用互斥锁等同步原语保护所有对stop的读写操作,同样能满足可见性要求。


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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.05 13:39:03