【问题标题】:C++: Is the assignment of a value to a primitive data type (e.g. bool) an atomic operation? [duplicate]C ++:将值分配给原始数据类型(例如bool)是原子操作吗? [复制]
【发布时间】:2018-09-20 11:36:26
【问题描述】:

想象有两个线程,一个分配一个值给(已经初始化的)布尔值,另一个线程读取/检查这个布尔值。如果对 bool 的访问没有受到保护或 bool 不是原子的,线程清理程序可能会在此处检测到可能的数据竞争。

这怎么可能?是否有可能分配给 bool 并不总是原子的,例如,因为缓存层次结构或乱序执行等硬件特性?

【问题讨论】:

  • bool 不是原子的,使用std::atomic<bool>
  • 问题不在于boolstd::atomic<bool> 之间的一般区别。正如@SkepticalEmpiricist 解释的那样,更多的是关于bool 的这种“中间撕裂效应”。

标签: c++ concurrency atomic


【解决方案1】:

尽管 C++ 标准没有强制要求,但实际上不可能在 x86 上的 bool 的“中间”获得 撕裂 效果,即仅部分更改值而另一个线程正在访问它。但是,CPU 可能是maintaining more than one copy of it, as a cache for each core for example.。因此,在另一个线程完成将其更改为新值之后,一个线程可能“看到”旧值。 std::atomic(特别是在您的情况下为std::atomic<bool>)为您提供memory barriers 来解决此问题。

【讨论】:

  • 如果没有 std::atomic,优化器可能会缓存读取和/或完全删除写入(到内存)。
  • @RichardCritten 如果您能提供链接源等,我很乐意编辑。我在写答案时找不到任何...
  • 我认为典型的缓存一致性协议,例如 intel 处理器上的 MESI 会确保线程无法从缓存中读取不同的值。
  • @Benski 我相信你是对的,只是它是通过使用 memory barriers 实现的——在 C++ 中你有这些 std::atomics。
  • @SkepticalEmpiricist 在发布此消息时正在处理它:blogs.msdn.microsoft.com/oldnewthing/20180924-00/?p=99805 "...汇编代码将 ptr 加载到寄存器中一次(在循环开始时),然后它将该寄存器指向的值与零进行比较。它从不重新加载 ptr 变量,因此它永远不会注意到线程将 ptr 的值更改为指向不同的值...."
猜你喜欢
  • 2010-12-09
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2019-05-23
  • 1970-01-01
  • 1970-01-01
  • 2019-05-05
相关资源
最近更新 更多