2017-10-07 125 views
0

道歉,如果这已经被回答,或者如果我失去了一些东西明显。嵌套的原子操作保证是原子吗?

我想了解原子的担保有多深去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()。我是正确的假设,这是保证原子存储2a

更重要的是,如果ab在线程T1T2之间共享,是它保证由两个线程进行a.store(++b);将会原子存储b增加的值(由相应的螺纹如看到的)进入a在每个线?换句话说,可以跟帖T2“屁股”,并增加b一次T1已经加过一次,但之前的结果是由T1存入a

+0

假设'B'被螺纹之间共享,'B'的增量可以之前'a.store(++ b)中发生;'。所以'a'的值不能保证是'2'。 – Jarod42

回答

2

增量是原子,和实体店是原子,但两者操作起来都没有。第一个线程可能会增加b,暂停,然后另一个线程增加b并将该值存储在a中,则第一个线程将恢复并将其b的值(现在的陈旧值)存储到a中。

+0

'b'只评估一次。所以从OP例子中a即使现在'b'是'3'也会存储'2'。 – Jarod42

+0

谢谢你,我怀疑很多,但它是件好事,它证实。所以不存在“嵌套”原子性这样的事情。 – cantordust

1

原子性不组成。

假设没有其他人曾经写到ab而另一个线程试图同时读取后,他们的存在,他们读b然后a,能够读取正是:

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

如果他们读a然后b

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

在这种情况下是一样的b然后a

+0

所以唯一的保证是读线程不能得到 '{a,b}' '{1,2}' 换句话说,'b'在它至少递增之前不会被存储在'a'中一旦。那是对的吗? – cantordust

1
a.store(++b); 

相当于

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

那么,有一个说法是前增量操作符不会创建一个临时值。 – cantordust

+0

我的意思是'operator ++'返回一个'int'而不是'std :: atomic ',所以'b'的未来修改不会影响存储在'a'中的值。 – Jarod42