假设我们有两个线程,一个是在循环中读取bool而另一个可以在特定时间切换它。我个人认为这应该是原子的,因为C ++中的sizeof(bool)
是1个字节而你不是部分读/写字节但是我想100%肯定。
是或否?
修改:
同样为了将来参考,同样适用于int
?
答案 0 :(得分:65)
C ++ 11中的“原子”类型有三个独立的问题:
撕裂:读或写涉及多个总线周期,并且在操作过程中发生线程切换;这可能会产生不正确的值。
缓存一致性:来自一个线程的写入更新其处理器的缓存,但不更新全局内存;从不同的线程读取读取全局内存,并且在其他处理器的缓存中看不到更新的值。
编译器优化:编译器在假设不从另一个线程访问这些值的情况下改组读取和写入的顺序,导致混乱。
使用std::atomic<bool>
可确保正确管理所有这三个问题。不使用std::atomic<bool>
会让你猜测,最多只能使用不可移植的代码。
答案 1 :(得分:18)
这完全取决于“原子”这个词的实际含义。
你的意思是“最终值将一次更新”(是的,在x86上,绝对保证一个字节值 - 以及任何正确对齐的值,至少64位),或“如果我将此设置为true(或false),在我设置之后没有其他线程会读取不同的值“(这不是很确定 - 你需要一个”lock“前缀来保证)。
答案 2 :(得分:7)
x86仅保证字对齐的字大小读写。它不保证任何其他操作,除非显式原子。另外,当然,您必须说服您的编译器首先实际发出相关的读写操作。