2017-02-02 2 views
4

私はシングルライターで、複数の読者の状況があります。あるスレッドが書き込みを行っているカウンタがあり、スレッドがこのカウンタを読み取る可能性があります。シングルスレッドはデータアクセスのために他のスレッドとの競合を心配する必要はないので、次のコードは安全ですか?atomic_loadのない原子変数を読み取ることはできますか?

#include <stdatomic.h> 
#include <stdint.h> 

_Atomic uint32_t counter; 

// Only 1 thread calls this function. No other thread is allowed to. 
uint32_t increment_counter() { 
    atomic_fetch_add_explicit(&counter, 1, memory_order_relaxed); 
    return counter; // This is the line in question. 
} 

// Any thread may call this function. 
uint32_t load_counter() { 
    return atomic_load_explicit(&counter, memory_order_relaxed); 
} 

ライター・スレッドはただのatomic_load*機能を呼び出すことなく、直接counterを読み込みます。これは安全でなければなりません(複数のスレッドが値を読み取ることは安全です)。しかし、変数_Atomicを宣言すると、その変数を直接使用することが制限されているか、 atomic_load*機能

+0

私は厳格な答えは「いいえ、それは安全ではない」であることをベンチャーだろうが、私は実際に右のそれを研究する時間がありません。今。更新可能な原子変数を直接読み取ろうとすると、更新自体がアトミックであるとみなされます。しかし、変数の更新がアトミックな場合、明示的にアトミックにする必要はありません。 –

答えて

1

はい、_Atomicオブジェクトで行うすべての操作は、順次整合性を持つ対応する呼び出しを発行するかのように行われます。あなたの特別なケースでは、評価はatomic_loadに相当します。

しかし、atomic_fetch_addを実行することによって評価された戻り値は、すでに別のスレッドによって変更されている可能性があるため、ここで使用されているアルゴリズムは間違っています。

これは、追加が2回行われているために最適ではないようですが、最適なオプティマイザでこれを並べ替えます。

+0

私はこれがシングルライターの状況だと言いました。私のコードでそれを行うことができる唯一のスレッドがあるので、 'counter'を変更する別のスレッドのリスクはありません。また、「_Atomic'オブジェクトで行うすべての操作は、連続した一貫性のある対応する呼び出しを発行したかのように保証されています」ということを示す標準への参照を持っていますか?私は標準からの読書を試みましたが、対応するアトミック関数の1つがなくても '_Atomic'変数を直接使用できると言及されていたところは見つかりませんでした。 – Cornstalks

+0

少し広がっています。基本的にすべての算術演算には、オブジェクトが原子修飾されている場合に何が起こるかを示す追加の句があります。 –

+0

ああ、関連する見積もりが見つかりました。 "原子型のオブジェクトの読み込みと格納は' memory_order_seq_cst'セマンティクスで行われます。 " (セクション6.2.6.1パラグラフ9)標準を見ると、あなたは正しいです。 (例えば、6.5.2.4/2のアトミックに関するポストインクリメント/デクリメント)。それを明確にしてくれてありがとう! – Cornstalks

0

あなたが機能を書き換えた場合は、この質問が消える:

uint32_t increment_counter() { 
    return 1 + atomic_fetch_add_explicit(&counter, 1, memory_order_relaxed); 
} 
+0

はい、これはこの問題を回避する方法です。これが私の実際のコードであれば良い考えです。しかし、私が投稿したコードは、私が書くことができる最も単純なMVCEであり、実際の質問を示しています。私の実際のコードでは、 'increment_counter'関数内の2つの行は実際には2つの異なる関数に分割されています(ただし、単一のスレッドだけが同じ制約を使用しています)。 – Cornstalks

関連する問題