1. ホーム
  2. c#

[解決済み] 連動と揮発性

2023-07-05 11:13:34

質問

状態を表すために使用している変数があります。この変数は、複数のスレッドから読み書きすることができます。

私は Interlocked.ExchangeInterlocked.CompareExchange で変更することができます。しかし、私は複数のスレッドからそれを読んでいます。

私が知っているのは volatile を使用すると、変数がローカルにキャッシュされず、常にメモリから直接読み込まれるようにすることができます。

しかし、変数をvolatileに設定すると、volatileの使用とInterlockedメソッドへのrefを使用した受け渡しに関する警告が発生します。

各スレッドがキャッシュされたバージョンではなく、変数の最新の値を読んでいることを確認したいのですが、volatile を使用することができません。

には Interlocked.Read がありますが、これは64ビット型用で、コンパクトフレームワークでは使用できません。これのドキュメントによると、32 ビット型ではすでに 1 回の操作で実行されるため、必要ないとのことです。

インターネット上では、すべてのアクセスに Interlocked メソッドを使用する場合は volatile は必要ない、という記述があります。しかし、Interlockedメソッドを使用して32ビット変数を読み取ることはできないので、すべてのアクセスにInterlockedメソッドを使用できるわけではありません。

ロックを使用せずに、変数のスレッドセーフな読み取りと書き込みを実現する方法はありますか。

どのように解決するのですか?

を使っているときは、この警告を無視しても大丈夫です。 Interlocked.Xxx 関数を使用している場合は、この警告を無視しても問題ありません ( この質問 を参照)、それらは常に揮発性の操作を行うからです。そのため volatile 変数は共有状態のために完全にOKです。もし、なんとしても警告をなくしたいのであれば、実際には ができます。 でインターロックリードを行うことができます。 Interlocked.CompareExchange (ref counter, 0, 0) .

編集してください。 実際には volatile が必要です。 だけです。 に直接書き込む場合 (つまり Interlocked.Xxx ). jerryjvl が言っているように のように、連動した(またはvolatile)操作で更新された変数の読み込みは、最新の値を使用します。