2012-02-15 9 views
1

私は私のコード(C#の.NET 4)で次のシナリオを持っている:同期の問題

私はfalseに初期化されているブール変数があります、今私は、スレッドの数をインスタンス化しています

bool b = false; 

をそれぞれの人がbの値を読む必要があるということです。 bを読み取る最初のスレッドは、その値をtrueに変更する必要があります(そして、いくつかのロジックを行います...)。他のスレッドは何もしません。値を読み取っているときに 'b'の同期メカニズムを使用する必要がありますか、値をtrueに設定している間だけロックすることはできますか? これは私のパフォーマンスを向上させる必要がありますが、私はその安全なIDを疑問に思って...

+0

これはどの言語ですか? – Tudor

答えて

5

をので、要件は以下のとおりです。スレッドはそれが必要false値を見れば

  • 複数のスレッドが単一bool変数
  • を読みますスレッドがtrue値を見ているならば、他に何もする必要があります
  • スレッドを1つだけ起こるべきではない、追加の作業
  • trueに変更し、実行します値を変更するので、コードは次のようになり、追加の作業

を実行するBLE:

public class Example 
{ 
    private bool b = false; 

    public void DoSomething() 
    { 
    if (!b) 
    { 
     b = true; 
     DoExtraStuff(); 
    } 
    } 
} 

これがDoSomethingを実行する複数のスレッドがあるとの意図があることであれば、当然のことながら、安全ではありませんDoExtraStuffは一度だけ実行してください。問題は、スレッドがbの読み取りと書き込みで競合することです。

実際には、読み書きをbアトミックにする必要があります。これはlockキーワードを使用して行うことができます。

public class Example 
{ 
    private bool b = false; 
    private object locker = new object(); 

    public void DoSomething() 
    { 
    bool trigger = false; 
    lock (locker) 
    { 
     if (!b) 
     { 
     b = true; 
     trigger = true; 
     } 
    } 

    if (trigger) 
    { 
     DoExtraStuff(); 
    } 
    } 
} 

Interlocked.CompareExhange介しCAS操作を使用して、代替のパターンがあります。残念ながら、boolを受け入れる過負荷はありませんが、boolintに変更する場合は、次のようにも動作します。

public class Example 
{ 
    private int b = 0; 

    public void DoSomething() 
    { 
    if (Interlocked.CompareExchange(ref b, 0, 1) == 0) 
    { 
     DoExtraStuff(); 
    } 
    } 
} 
+0

あなたは正しいです。複数のスレッドが '!b'を真と見なし、if-blockに入ることがあります。 – Ajay

+0

はい、そうです、これは正しいバージョンです。うまくいけば、私の答えを削除することができますので、OPが周りに来て、受け入れられた答えを変更します。私は彼がしたいことを誤解しているようです。 – Tudor

+0

@ Tudor:ええ、誤解の質問は私にはたくさん起こります。この質問の文言は少し良いかもしれません。 –