80 c++ atomicity c++11 stdatomic
不是atomic<bool>
多余的,因为bool
它本质上是原子的吗?我认为不可能有部分修改的bool值.我什么时候真的需要用atomic<bool>
而不是bool
?
Ker*_* SB 87
C++中的任何类型都不是"原子性的",除非它是一个std::atomic*
东西.那是因为标准这样说.
在实践中,为操纵a std::atomic<bool>
而发出的实际硬件指令可能(或可能不)与普通硬件指令相同bool
,但是原子是更大的概念,具有更广泛的分支(例如对编译器重新排序的限制).此外,一些操作(如否定)在原子操作上过载,以在硬件上创建与非原子变量的本机非原子读 - 修改 - 写序列明显不同的指令.
Dim*_*ims 61
记住记忆障碍.尽管可能无法bool
部分更改,但多处理器系统可能在多个副本中具有此变量,并且即使在另一个线程将其更改为新的后,一个线程也可以看到旧值.Atomic引入了内存屏障,因此变得不可能.
Pet*_*ker 24
C++的原子类型处理三个潜在的问题.首先,如果操作需要多个总线操作,那么读取或写入可能被任务切换器撕裂(并且可能发生在a bool
,具体取决于它的实现方式).其次,读取或写入可能仅影响与正在执行操作的处理器相关联的高速缓存,并且其他处理器可能在其高速缓存中具有不同的值.第三,如果编译器不影响结果,编译器可以重新排列操作的顺序(约束有点复杂,但现在已经足够了).
您可以通过明确刷新缓存以及使用特定于编译器的选项来防止重新排序来假设您正在使用的类型是如何实现的,从而自己处理这三个问题中的每一个(并且,不,volatile
不执行此操作)除非您的编译器文档说它确实).
但为什么要经历这一切呢?atomic
为你照顾它,并且可能比你自己做得更好.
And*_*zos 19
考虑比较和交换操作:
bool a = ...;
bool b = ...;
if (a)
swap(a,b);
Run Code Online (Sandbox Code Playgroud)
在我们读完之后,我们得到了真的,另一个线程可能会出现并设置为false,然后我们交换(a,b),因此在退出b之后为false,即使交换已经完成.
使用std::atomic::compare_exchange
我们可以原子地执行整个if/swap逻辑,这样另一个线程就无法在if和swap之间设置为false(没有锁定).在这种情况下,如果进行交换,则b在退出时必须是假的.
这只是适用于两种值类型(如bool)的原子操作的一个示例.
hus*_*had 18
原子操作不仅仅是撕裂的价值,所以虽然我同意你和其他海报,我不知道bool
有可能出现撕裂的环境,但还有更多危险.
Herb Sutter对此进行了精彩的讨论,您可以在线查看.请注意,这是一个漫长而有牵连的谈话.Herb Sutter,Atomic Weapons.问题归结为避免数据争用,因为它允许您具有顺序一致性的错觉.
某些类型的原子性完全取决于底层硬件.每个处理器体系结构对某些操作的原子性有不同的保证.例如:
Intel486处理器(以及之后的新处理器)保证始终以原子方式执行以下基本内存操作:
- 读或写一个字节
- 读取或写入在16位边界上对齐的字
- 读取或写入在32位边界上对齐的双字
其他架构对于哪些操作是原子的具有不同的规范.
C++是一种高级编程语言,力求从底层硬件中抽象出来.出于这个原因,标准根本不允许人们依赖这种低级别的假设,否则您的应用程序将无法移植.因此,C++中的所有原始类型atomic
都由符合C++ 11标准的开箱即用的标准库提供.
归档时间: |
|
查看次数: |
52674 次 |
最近记录: |