CodeWalk

volatile与内存屏障的关系与区别

作者:编译有声 · 2026-05-30 12:55

C++中volatile关键字和内存屏障(Memory Barrier)的关系是什么?volatile是否能保证多线程内存可见性?为什么说volatile不适合线程间同步?volatile的正确使用场景是什么?

回答

编译有声

volatile的作用

  1. 禁止编译器寄存器缓存(每次读取从内存重新加载)
  2. 禁止编译器对volatile操作重排序
  3. 不产生任何CPU指令级内存屏障
  4. 不保证原子性(多线程读写可能产生数据竞争)

volatile vs 内存屏障: | 特性 | volatile | 内存屏障 | |------|----------|---------| | 编译器重排 | 阻止 | 阻止 | | CPU重排 | 不阻止 | 阻止 | | 可见性保证 | 无 | 有(Acquire/Release) | | 原子性 | 无 | 需配合atomic |

为什么不能用于线程同步

volatile bool ready = false;
// 线程1
ready = true;  // 其他核心可能看不到此写入
// 线程2
if (ready) { } // 可能永远看不到ready=true

正确的做法是使用std::atomic<bool>或互斥锁。

volatile的正确使用场景

  1. 硬件寄存器映射volatile uint32_t* reg = (uint32_t*)0x4000;——保证每次读写都访问设备
  2. 信号处理程序:C++11后std::atomic_signal_fence更合适
  3. setjmp/longjmp场景:变量可能被longjmp修改
  4. 与多线程无关的特殊内存访问:如DMA缓冲区

C++标准说明[ISO C++ 7.1.6.1]:volatile是给编译器的提示——变量可能被程序外部修改。与线程无关。