嵌套的原子操作是否保证是原子的?
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
中?
更重要的是,如果a
和b
在线程T1
和T2
之间共享,是否保证两个线程执行的a.store(++b);
是要在每个线程中以原子方式将 b
的增量值(如各个线程所见)存储到 a
中?换句话说,可以线程 T2
"butt in" 并再次递增 b
在 T1
已经递增一次但 在之前,结果被T1
?
存储到a
增量是原子的,存储是原子的,但是两个操作加在一起不是。第一个线程有可能递增 b
,被挂起,然后另一个线程递增 b
并将该值存储在 a
中,然后第一个线程恢复并存储它(现在陈旧) b
的值转换为 a
.
原子性不组合。
假设没有其他人写入 a
和 b
并且另一个线程在它们存在后尝试读取它们,并且他们读取 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);
如果这个问题已经得到解答,或者我遗漏了一些明显的东西,我们深表歉意。
我试图了解 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
中?
更重要的是,如果a
和b
在线程T1
和T2
之间共享,是否保证两个线程执行的a.store(++b);
是要在每个线程中以原子方式将 b
的增量值(如各个线程所见)存储到 a
中?换句话说,可以线程 T2
"butt in" 并再次递增 b
在 T1
已经递增一次但 在之前,结果被T1
?
a
增量是原子的,存储是原子的,但是两个操作加在一起不是。第一个线程有可能递增 b
,被挂起,然后另一个线程递增 b
并将该值存储在 a
中,然后第一个线程恢复并存储它(现在陈旧) b
的值转换为 a
.
原子性不组合。
假设没有其他人写入 a
和 b
并且另一个线程在它们存在后尝试读取它们,并且他们读取 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);