bool读/写操作可以在x86上不是原子操作吗?

szx*_*szx 27 c++ x86 boolean atomic

假设我们有两个线程,一个是在循环中读取bool而另一个可以在特定时间切换它.我个人认为这应该是原子的,因为sizeof(bool)在C++中是1个字节而你不是部分读/写字节但我想100%肯定.

那么是或否?

编辑:

另外供将来参考,同样适用于int

Pet*_*ker 67

C++ 11中的"原子"类型有三个独立的问题:

  1. 撕裂:读或写涉及多个总线周期,并且在操作过程中发生线程切换; 这可能会产生不正确的值.

  2. 缓存一致性:来自一个线程的写入更新其处理器的缓存,但不更新全局内存; 从另一个线程读取读取全局内存,并且在其他处理器的缓存中看不到更新的值.

  3. 编译器优化:编译器在假设不从另一个线程访问这些值的情况下改组读取和写入的顺序,从而导致混乱.

使用std::atomic<bool>可确保正确管理所有这三个问题.不使用std::atomic<bool>你猜测的叶子,最好是不可移植的代码.

  • 另请参阅[程序员对 CPU 缓存的看法](https://software.rajivprab.com/2018/04/29/myths-programmers- believe-about-cpu-caches/) 回复:手动一致性。C++ 是围绕*一致*共享内存的假设而设计的,因此您需要做的就是确保存储或加载实际上发生在 asm 中,而不是将值保留在寄存器中。在具有非一致性共享内存的假设机器上,每个同步都必须刷新所有内容(或需要大量跟踪),但我不知道具有非一致性共享内存的标准线程的任何 C++ 实现。 (2认同)

Mat*_*son 18

这一切都取决于你对"原子"这个词的实际含义.

你的意思是"最终值将一次更新"(是的,在x86上,绝对保证一个字节值 - 以及任何正确对齐的值,至少64位),或"如果我将其设置为真(或在我设置之后,没有其他线程会读取不同的值"(这不是很确定 - 你需要一个"锁定"前缀来保证).

  • @jberryman:问题来自缓存以及编译器优化内存的读取.某个线程中的`b = false;`并不能保证所有其他线程在下一个`if(b)...`的情况下,将接收到`b`是假的.这要求编译器没有将对`b`的访问优化为`tmp = b; ... if(tmp)...`[其中`tmp`是寄存器].根据线程内的代码,有时编译器会这样做. (2认同)

Pup*_*ppy 6

x86仅保证字对齐的字大小读写.它不保证任何其他操作,除非显式原子.另外,当然,您必须说服您的编译器首先实际发出相关的读写操作.


归档时间:

查看次数:

12079 次

最近记录:

6 年,2 月 前