2017-10-07 8 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()です。これがにアトミックに2を格納することが保証されていると仮定するのは正しいですか?

abスレッド T1T2間で共有される場合にさらに重要なことに、それは両方のスレッドによって実行される a.store(++b);がそれぞれアトミック aに(それぞれのスレッドで見られるように) bのインクリメント値を格納しようとしていることが保証される

糸?言い換えれば、「バット」T2スレッドとbをインクリメントすることができますもう一度T1後には既に一度それをインクリメントしているが、前に結果がT1aに格納されていますか?

+0

がB'は、スレッド間で共有される '仮定に相当し、 'B'の増分はa.store(++ B)'の前に発生する可能性があり、 '。 'a'の値は' 2'を保証しません。 – Jarod42

答えて

2

インクリメントはアトミックであり、ストアはアトミックですが、2つの操作は一緒ではありません。最初のスレッドがbをインクリメントし、一時停止し、別のスレッドがbをインクリメントしてその値をaに格納すると、最初のスレッドが再開し、bの値をaに保存します。

+0

'b'は1回だけ評価されます。したがって、OPの例から、aは、現在「b」が「3」であっても、「2」を記憶する。 – Jarod42

+0

ありがとうございます、私はそれほど疑っていますが、それを確認されていることは良いことです。したがって、「ネストされた」原子性のようなものはありません。 – cantordust

1

原子性は構成されません。可能性は読み込み、誰もが今までabに書き込むことはありませんし、別のスレッドが読み取ろうとするの両方が存在する後と仮定すると、彼らはaその後、bを読ん

は正確です:

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

彼らはその後、baを読めば:この場合b次いでa同じである

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

+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 ++'が 'std :: atomic 'ではなく' int'を返すので、 'b'の将来の変更は' a'に格納された値に影響しません。 – Jarod42

関連する問題