3

type の共有変数がありdoubleます。この変数は、2 つのスレッドによってアクセスされます。一方のスレッドは変数を書き込むだけで、もう一方のスレッドは変数を読み取るだけです。

ここでも競合状態が発生しますか? はいの場合、C++ でアトミック アクセスを実装する「簡単な」方法はありますか? 書き込みよりも読み取りの方がはるかに多い場合、効率的に実装するにはどうすればよいですか? 変数を としてマークする必要がありますvolatileか?

編集:「リーダー」スレッドはデータのバッチで定期的に機能し、新しい値の伝播は時間に敏感ではありません。テストする良い方法がない複雑なインターロックを実装する代わりに、ライター スレッドが書き込む別の一時変数を宣言するだけで済みます。次に、リーダーが 1 つのバッチで終了すると、一時値をアトミックに実際の変数に伝達できます。それはレースコンディションフリーでしょうか?

4

2 に答える 2

8

はい、double変数はほとんどのプロセッサでアトミックではないため、競合状態があります。

3 つの double を使用します (おそらく、間に余分なパディングを入れた配列で、パフォーマンスを低下させる誤った共有を回避します)。

1 つはリーダーが所有し、もう 1 つはライターが所有し、もう 1 つはハンドオフされています。

書き込み: 書き込みスロットに書き込み、書き込みスロットInterlockedExchangeのポインタ/インデックスをハンドオフ スロットのインデックスとアトミックに (たとえば で) スワップします。インデックスはポインタ サイズ以下であるため、変数が適切に配置されている限り、アトミック スワッピングは簡単です。たまたまプラットフォームがメモリ バリアの有無にかかわらずインターロック交換を提供している場合は、あるものを使用してください。

読み取るには: 読み取りスロットのポインター/インデックスを、ハンドオフ変数のインデックスとアトミックに交換します。次に、読み取りスロットを読み取ります。

読み取りスレッドは最新のスロットと前のスロットの間でバウンスする傾向があるため、実際にはバージョン番号も含める必要があります。読むときは、スワップ前後の両方を読んで、新しいバージョンのものを使ってください。

または、C++11 では、単に使用しますstd::atomic

警告: 上記は単一のライター/単一のリーダーに対してのみ機能します (この質問の特定のケース)。複数ある場合は、変数へのすべてのアクセスを保護するリーダー/ライター ロックなどを検討してください。

于 2012-04-17T22:35:01.163 に答える
0

プリミティブ型の読み取り/書き込みについて説明している this を参照してください。

C++ の int の読み取りと書き込みはアトミックですか?

于 2012-04-17T22:35:22.943 に答える