使用c++ atomic时写"y=++x"安全吗?

Is it safe to write "y=++x" when using c++ atomic?

如果我有 2 个线程并且在 main 函数中,我会像这样初始化一个变量 x

std::atomic<int> x=0;,

在线程 1 中,我这样做:

while(true){
  x++;
}

在线程 2 中,我这样做:

y=++x;

我的问题是 that:is 变量 y 有没有可能得到错误的数字?

我的意思是例如:

如果在线程2中,此时x=2;那么因为"++x",x=3,所以我希望y=3;

但是我怕在"++x"和"y=x"之间,线程1会再次重写x,所以我可能有y=4什么的。

is there any possibility that variable y can get the wrong number?

完全取决于您认为的 "wrong" 数字。 y 几乎可以有任何值,这取决于 trhead1 中的循环重复了多少次。

y 将保证获得 x 在预增量操作后的值。

x 确实可以在赋值之前递增,因此 x 的值可能大于 y 的值。关于 y 的值,我们唯一可以预测的是它不会大于 x.

如果一个线程写入原子 object 而另一个线程从中读取,则行为是 well-defined。所以答案是否定的,y不能得到一个"wrong"值,这就是<atomic>header.

的全部目的

Pre-increment 和 post-increment 原子操作也是原子操作。

来自man page

T operator++() noexcept; 
T operator++() volatile noexcept;

Atomically increments or decrements the current value. The operation is read-modify-write operation.
1) Performs atomic pre-increment. Equivalent to fetch_add(1)+1.

所以是的,它很安全。

But I am afraid that between "++x" and "y=x",thread 1 will rewrite x again,so I may have y=4 or something.

线程 1 可能会再次重写 x,但线程 2 不会再次读取 x 的值,因此如果发生这种情况,它不会对线程 2 产生任何影响。分配给 y 的值取自从 fetch_add().

返回的 private/temporary

是的,您会得到正确的值。该接口保证该值将递增并 return 自动编辑。它还指出结果是按值 return 编辑的(而大多数预增量将 return 对现在增加的对象的引用)以避免其他线程进行任何意外更改。

这里是the docs.

如果担心 y=++xx 中的值首先等于 2,然后通过 ++x 增加到 3,然后在复制到 [= 之前​​再次由另一个线程增加13=],那么答案是否定的——这不可能发生。操作 ++x 的结果不是对原子值本身的引用 - 它是 post-increment 的简单 int 结果,并且该操作保证您将在增量返回后获得准确的值(无需额外阅读)。