无同步机制下,共享内存写入后其他进程何时能读取到更新值?
共享内存无同步情况下的读取一致性问题
假设存在两个进程,它们共享一块内存(shared memory),且都持有指向共享内存起始地址的指针。场景如下:进程1向共享内存的某个偏移位置写入数据,进程2持续循环从该偏移位置拷贝数据。未使用锁或原子操作强制内存同步。
进程1代码
char *sh_mem; size_t offset; char data[4]; memcpy(sh_mem + offset, data, 4);
进程2代码
char *sh_mem; size_t offset; char read[4]; while (true) memcpy(read, sh_mem + offset, 4);
两者使用相同的偏移量,相关疑问如下:
- 经过多长时间后,能确保进程2读取到进程1更新后的值?
- 是否存在某种机制能保证进程2最终会发现其读取的缓存块已脏,并获取更新后的块?
核心结论
- 无确定的读取时间:在没有内存同步机制(锁、原子操作、内存屏障)的前提下,不存在任何可以保证进程2读到更新后数据的时间点。
- 无强制更新的保障机制:没有任何机制能确保进程2最终一定会发现缓存块已脏并加载新值。
详细解释
- 缓存架构导致的不一致:现代CPU的多级缓存设计中,进程1写入共享内存时,数据可能仅停留在自身CPU的缓存层级中,不会立即同步到主存;而进程2所在的CPU可能持续从本地缓存读取旧数据,完全感知不到其他CPU缓存或主存中的数据更新。
- 编译器与CPU的优化干扰:编译器可能对进程1的写操作进行延迟优化,CPU也可能乱序执行指令,导致写操作的实际生效时间完全不可预测;进程2的循环读操作则可能被优化为重复读取本地缓存,甚至不会触发任何主存访问请求。
- 标准层面的未定义行为:从C语言标准和CPU架构规范来看,这种未加同步的跨进程内存读写属于未定义行为,“永久读取旧值”是完全合规的结果。
内容的提问来源于stack exchange,提问作者W1nTer003
相关产品推荐
相关产品推荐

