一元增量算子的原子行为

use*_*805 8 c c++ atomic increment

在某处我读到一元运算符本质上是原子的,所以它们可以在多线程环境中使用.为了证实这一点,我写了两个单独的程序

  1. 我使用变量x并使用一元运算符++ x递增
  2. 我使用变量x并使用x = x + 1递增

我比较了两个程序的反汇编,发现没有区别.请提供您的意见.

Vit*_*meo 13

在某处我读到一元运算符本质上是原子的,所以它们可以在多线程环境中使用.

那个来源是完全错误的.您需要使用std::atomic(或等效的C)来实现原子性 - 一元操作并不特殊.


我比较了两个程序的反汇编,发现没有区别

这并不意味着生成的操作是原子的.没有区别,因为任何体面的编译器都会优化x=x+1++x进入同一个程序集(假设内置类型).


Bat*_*eba 5

一元运算符必然是原子的断言是一个神话.

例如,++x需要读取和写入才能x打开数据竞争的机会.

++x编译x = x + 1为不相关的相同代码的事实.

如果您想避免数据争用,那么如果没有适当的原子类型,则使用原子类型或互斥单元.为避免疑问,int不一定是原子类型.


JVA*_*pen 5

编写跨平台C++时,使用时只有原子行为std::atomic<>.

确实,在某些平台上,如英特尔64位,处理器保证inc是原子的.但是,请不要编写依赖于此的代码!作为您未来的调试器,我想知道哪些数据是通过线程共享的,哪些不是.

使用std::atomic<int>可能需要更多的工作来编写,但是,它确实通过回退到平台需求(std :: atomic :: is_lock_free)或者通过显式地锁定来保证一切行为原子(在每个平台上).访问.它还插入防护装置以确保其他处理器核心的高速缓存无效(如果平台需要这样).

在英特尔64位的实践中,这应该给你相同的程序集,如果没有,记录你的编译器的错误.

同时,某些带有int的操作可能不是原子操作(operator*=),std::atomic根本不支持这些操作,要求您正确使用它们.

在旁注:++x并且x = x+1是不同的操作,它们可能被优化为相同的组件.鉴于非原子平台要求,第二个突然是一个需要数天才能解决的错误.