質問

にアクセスしています ブール C#のフィールドアトミック?特に、ロックを設定する必要がありますか?

class Foo
{
   private bool _bar;

   //... in some function on any thread (or many threads)
   _bar = true;

   //... same for a read
   if (_bar) { ... }
}
役に立ちましたか?

解決

はい。

次のデータ型の読み取りと書き込みはアトミックです。bool、char、byte、sbyte、short、ushort、uint、int、float、参照型。

で見つかったように C# 言語仕様.

編集:おそらく、次のことを理解することも価値があるでしょう。 揮発性の キーワード。

他のヒント

上で述べたように、bool はアトミックですが、それを使用して何をしたいかにも依存することを覚えておく必要があります。

if(b == false)
{
    //do something
}

現在のスレッドがIFステートメントの後にコードを実行する前に、B値が変化する可能性があることを意味する原子操作ではありません。

bool アクセスは確かにアトミックですが、それだけではありません。

「不完全に書き込まれた」値を読み取ることを心配する必要はありません。いずれの場合でも、それがブール値にとって何を意味するかは不明です。しかし、少なくとも詳細が記載されている場合は、プロセッサーのキャッシュについて心配する必要があります。タイミングが問題です。コア A で実行されているスレッド #1 に _bar キャッシュ内、そして _bar 別のコアで実行されているスレッド #2 によって更新されます。ロックを追加して宣言しない限り、スレッド #1 は変更をすぐには認識しません。 _bar として volatile, 、またはへの呼び出しを明示的に挿入します。 Thread.MemoryBarrier() キャッシュされた値を無効にします。

私が使用し、正しいと思うアプローチは、

volatile bool b = false;

.. rarely signal an update with a large state change...

lock b_lock
{
  b = true;
  //other;
}

... another thread ...

if(b)
{
    lock b_lock
    {
       if(b)
       {
           //other stuff
           b = false;
       }
     }
}

基本的な目標は、めったに発生しない大量の状態変更情報を提供するためにオブジェクトをロックする必要があるかどうかを確認するために、反復ごとにオブジェクトを繰り返しロックする必要を避けることでした。私 考える このアプローチは機能します。そして、絶対的な一貫性が必要な場合は、 考える b bool には volatile が適切です。

ライセンス: CC-BY-SA帰属
所属していません StackOverflow
scroll top