简体   繁体   中英

Are nested atomic operations guaranteed to be atomic?

Apologies if this has been answered already, or if I'm missing something obvious.

I'm trying to understand how deep the guarantees of atomicity go for std::atomic . For example, if we have

std::atomic<int> a(0);
a.store(1);

the store operation is atomic. However, what happens if we have nested atomic operations, such as this:

std::atomic<int> a(0);
std::atomic<int> b(1);
a.store(++b);

My understanding is that ++b is atomic, and so is store() . Am I right to assume that this is guaranteed to store 2 atomically in a ?

More importantly, if a and b are shared between threads T1 and T2 , is it guaranteed that a.store(++b); performed by both threads is going to store the incremented value of b (as seen by the respective threads) into a atomically in each thread? In other words, can thread T2 "butt in" and increment b once more after T1 has already incremented it once but before the result is stored into a by T1 ?

The increment is atomic, and the store is atomic, but the two operations together are not. It is possible for the first thread to increment b , get suspended, then another thread increments b and stores that value in a , then the first thread resumes and stores it's (now stale) value of b into a .

Atomicity does not compose.

Assuming nobody else ever writes to a and b and another thread tries to read both after they exist, and they read b then a , possible reads are exactly:

{b,a}
{1,0}
{2,0}
{2,2}

if they read a then b :

{a,b}
{0,1}
{0,2}
{2,2}

which in this case is the same as b then a .

a.store(++b);

is equivalent to

int temp = ++b;
/* other threads can modify `b` but its value has been save in temp ... */
a.store(temp);

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM