32

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

所以是还是不是?

编辑

也供将来参考,是否同样适用于int

4

3 回答 3

73

C++11 中的“原子”类型解决了三个不同的问题:

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

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

  3. 编译器优化:编译器在不从其他线程访问值的假设下打乱读写顺序,导致混乱。

使用std::atomic<bool>可确保正确管理所有这三个问题。不使用std::atomic<bool>会让你猜测,充其量是不可移植的代码。

于 2013-01-31T11:53:10.210 回答
19

这完全取决于您所说的“原子”一词的实际含义。

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

于 2013-01-31T11:46:07.837 回答
6

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

于 2013-01-31T11:46:07.183 回答