共享布尔值的缓存一致性 c++11

use*_*088 1 c++ multithreading caching

我有一个结构数组,它是一个全局变量,其中一个结构成员是布尔值。特定 CPU 中的一个线程正在读取布尔值,不同 CPU 中的另一个线程可以通过将布尔值分配为 true 或 false ( my_array[index].bool = true/false)来定期更改布尔值。

我知道不使用任何形式的同步机制将导致未定义的行为。

但是,假设:

  1. 在我的实现中sizeof(bool)==1
  2. 一篇文章中,将一个字节的布尔变量设置为 true/false 将是 x86_64 位系统上的原子操作,
  3. 并且这个答案第 3 段表明 MESIF 协议将保持多个内核的缓存一致(包括不同内核的 L1 私有缓存)
  4. 我的代码只能在带有 gcc 4.8.4 编译器优化标志 O3 的 64 位 x86 架构上运行

我可以肯定地说,在上述条件下,我可以在不使用互斥锁等同步机制的情况下逃脱,并且没有未定义的行为吗?

Dav*_*rtz 5

不,你不能肯定地说,因为没有标准提供这种保证。当您通过组合来自许多地方的信息“综合”一个保证并最终依靠您无法想到任何可能失败的方式时,您就没有确定性。

有很多这样的例子,人们认为他们以这种方式确定,然后事情以他们无法想到的方式失败。也就是说,我也想不出任何可能会失败的方法,但我不会依赖它。

请注意,您不应期望内存操作提供任何排序​​,只是一个线程中的更改最终将在另一个线程中可见。特别是,您不能假设看到特定布尔值更改的线程将看到代码中出现在该操作之前的任何内存操作。编译器和 CPU 可以自由地并在实践中重新排序内存操作。

因此,即使有保证,您也无法使用它。即使将它用于布尔值来关闭while (!shutdown) do_work();一个线程和shutdown = true;另一个线程中的线程也是有风险的。如果编译器可以证明do_work()无法修改shutdown,它可以优化检查shutdown并且循环可能永远不会终止。