GCC Wiki内存屏障示例中,断言B为何会失败?
为什么断言B也会失败?
先贴出示例代码:
// -Thread 1- y.store (20, memory_order_relaxed) x.store (10, memory_order_relaxed) // -Thread 2- if (x.load (memory_order_relaxed) == 10) { assert (y.load(memory_order_relaxed) == 20) /* assert A */ y.store (10, memory_order_relaxed) } // -Thread 3- if (y.load (memory_order_relaxed) == 10) assert (x.load(memory_order_relaxed) == 10) /* assert B */
核心原因是**memory_order_relaxed不提供任何跨线程的内存同步或顺序保证**——它只保证单个原子变量的操作是原子的,但不同原子变量的操作在跨线程时的可见性和顺序完全不受约束,也不会建立任何happens-before关系。
断言B失败的具体逻辑
你以为y.load() ==10意味着线程2已执行完毕,线程3必然能看到x=10,但这个逻辑不成立:
- 线程2的
x.load() ==10成立,仅说明线程2自身缓存中读到了x的新值10,但这个缓存状态不会自动同步给其他线程(比如线程3)。 - 线程2执行
y.store(10)后,这个操作的结果可能通过缓存一致性协议快速同步到线程3的缓存,但线程1的x.store(10)结果可能还没同步到线程3的缓存。 - 当线程3看到
y=10并立即执行x.load()时,它读取的是自己缓存里的x旧值(比如初始的0),此时断言B就会失败。
简单说,memory_order_relaxed下线程间的内存可见性没有传递性:线程2看到了x的新值,不代表线程3在看到y的新值时也能看到x的新值——没有同步机制(比如release-acquire对)来强制这种可见性传递。
内容的提问来源于stack exchange,提问作者hk134579
相关产品推荐
相关产品推荐

