0

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.

2
  • I'm inclined to think this question answers yours. Commented May 25, 2020 at 3: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. Commented May 25, 2020 at 3:56

5 Answers 5

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).

Sign up to request clarification or add additional context in comments.

Comments

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.

Comments

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.

Comments

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().

Comments

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.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.