是+ =,| =,&=等原子?

SF.*_*SF. 32 c c++ atomic operators thread-safety

就像是"修改"运营商+=,|=,&=等原子?

我知道++是原子的(如果你x++;同时在两个不同的线程中执行),你总是会x增加2,而不是x=x+1关闭优化.)

我想知道是否variable |= constant,以及喜欢是线程安全的还是我必须使用互斥锁来保护它们?

(...或者它是否依赖于CPU?在这种情况下,它在ARM上是怎么回事?)

小智 75

你错了.不能保证++是原子的,也不能保证复合赋值运算符,或者实际上对于任何C++操作.

  • @SF不,不是.它是特定于编译器的.仅仅因为CPU架构有一条指令并不意味着编译器会以你认为应该的方式使用它,如果它确实使用它的话. (24认同)
  • 这意味着这是特定于CPU的.在允许"inc [address]"的单核架构上,这绝对是原子的. (3认同)
  • 即使编译器可以生成原子增量,x ++是否可以是原子的,也可能取决于x的数据类型.例如,在SF的目标上,如果x为"long long",则x的增量将不是原子的,如果它是另一种整数类型,则可以想象它可能取决于特定的ARM体系结构和数据对齐. (3认同)
  • 至少在C++ 0x之前:"本条款描述了用于细粒度原子访问的组件.这种访问是通过对原子对象的操作提供的." [n3035草案中的29.1/1]. (2认同)
  • @SF:这非常具体.如果编译器选择不使用该指令怎么办?如果/当您升级到多核系统时会怎样?那些没有'inc`指令的架构怎么样?*一般来说*,`++`不是**原子.你刚刚发现了一个狭窄的特殊情况,它不是一个问题 (2认同)

Ale*_*ski 9

x++ 通常用3条指令实现:将X读入寄存器,递增,然后将其写回存储器.

你的帖子可能会被抢先一步.

  • 在某些处理器上,甚至单个指令也可以是非原子的。 (2认同)

Ben*_*nno 6

为了使值的变化在核心之间可见,+ =(例如)必须加载值,添加增量然后存储它.这意味着该操作不会是原子的.

为了确保原子性,您需要在操作周围进行适当的锁定.