嵌套的原子操作是否保证是原子的?

Are nested atomic operations guaranteed to be atomic?

如果这个问题已经得到解答,或者我遗漏了一些明显的东西,我们深表歉意。

我试图了解 std::atomic 的原子性保证有多深。例如,如果我们有

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

存储操作是原子的。但是,如果我们有嵌套的原子操作会发生什么,例如:

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

我的理解是++b是原子的,store()也是。我是否可以假设这保证以原子方式将 2 存储在 a 中?

更重要的是,如果ab在线程T1T2之间共享,是否保证两个线程执行的a.store(++b);是要在每个线程中以原子方式将 b 的增量值(如各个线程所见)存储到 a 中?换句话说,可以线程 T2 "butt in" 并再次递增 b T1 已经递增一次但 之前,结果被T1?

存储到a

增量是原子的,存储是原子的,但是两个操作加在一起不是。第一个线程有可能递增 b,被挂起,然后另一个线程递增 b 并将该值存储在 a 中,然后第一个线程恢复并存储它(现在陈旧) b 的值转换为 a.

原子性不组合。

假设没有其他人写入 ab 并且另一个线程在它们存在后尝试读取它们,并且他们读取 b 然后 a,可能的读取正是:

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

如果他们读 a 那么 b:

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

在这种情况下与 b 相同,然后是 a

a.store(++b);

相当于

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