-1

If I have 2 threads and in main function, I init a variable x like this

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

In thread 1 I do this:

while(true){
  x++;
}

And In thread 2 I do this:

y=++x;

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

I mean for example:

if in thread2,at that moment,x=2;then because of "++x",x=3,so I hope y=3;

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

curiousguy
  • 8,038
  • 2
  • 40
  • 58
scirocc
  • 153
  • 6
  • I'm inclined to think [this question](https://stackoverflow.com/questions/31978324/what-exactly-is-stdatomic) answers yours. – Tas May 25 '20 at 03:50
  • I think you don't know the meaning of `atomic` because your question is about `y` not `x`. If you have two threads and `x=0` at the beginning, at the end, `x` will be 2 but `y` will depend on the order (i.e) you can't know `y` value unless you don't know the order. – asmmo May 25 '20 at 03:56

5 Answers5

3

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

Depends entirely on what you would consider a "wrong" number. y could have pretty much any value which depends on how many times the loop in trhead1 has repeated.

y would be guaranteed to get the value that x had after the pre-increment operation.

x can indeed be incremented before the assignment, so it is possible for x to have a greater value than y has. The only thing we can predict about the value of y is that it is not greater than x.

eerorika
  • 232,697
  • 12
  • 197
  • 326
3

Yes you will get the correct value. The interface guarantees that the value will be incremented and returned atomically. It also states that the result is returned by value (whereas most pre-increments will return a reference to the now-incremented object) to avoid any unexpected changes by other threads.

Here are the docs.

Buddy
  • 10,874
  • 5
  • 41
  • 58
3

If the concern is that in y=++x value in x equals to 2 first, then increased to 3 by ++x, then increased by another thread again before copying to y, then answer is no - this can't happen. Result of operation ++x is not a reference to the atomic value itself - it is plain int result of post-increment and the operation guarantees that you will have exactly the value after increment returned (without additional read).

Alexander Pivovarov
  • 4,850
  • 1
  • 11
  • 34
2

From the 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.

So yes, it's safe.

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

thread 1 might rewrite x again, but thread 2 won't read value of x a second time, so it won't make any difference to thread 2 if that happens. The value assigned to y is taken from a private/temporary that was returned from fetch_add().

Jeremy Friesner
  • 70,199
  • 15
  • 131
  • 234
0

If one thread writes to an atomic object while another thread reads from it, the behavior is well-defined. So the answer is no, y can not get a "wrong" value, this is the whole purpose of <atomic> header.

Pre-increment and post-increment operations on atomics are atomic too.

dgrandm
  • 375
  • 3
  • 12