3

lock ステートメントを使用すると、「あるスレッドがコードのクリティカル セクションに入っているときに、別のスレッドがクリティカル セクションに入らないようにすることができます。別のスレッドがロックされたコードに入ろうとすると、オブジェクトが解放されるまで待機し、ブロックします。 ."

別のスレッドがロックされたコードに入ろうとした場合に、(ロックが解放されるのを待つのではなく) コード全体をスキップするという動作が必要な場合はどうすればよいでしょうか? 私の頭に浮かぶアイデアは、次のようなフラグを使用することです

if(flag) return;
flag = true;
//do stuff here
flag =false;

しかし、2 つのスレッドが true に設定される前に 2 つのスレッドが最初の行を通過する可能性があるか、例外が発生した場合にフラグが false に設定されないため、これは安全ではないことを私は知っています。

4

3 に答える 3

5

のこのオーバーロードを使用Monitor.TryEnterすると、タイムアウトを指定できます。

指定された時間の間、指定されたオブジェクトの排他ロックを取得しようとします。

戻り値タイプ:System.Boolean現在のスレッドがブロックせずにロックを取得した場合はtrue。それ以外の場合はfalse。

あなたの場合、おそらくに近い TimeSpan.Zeroタイムアウトを使用したいと思うでしょう。

スレッドがロックを取得しようとして一定時間待機したくない場合は引数を受け入れないこのオーバーロードだけを実行できます。このメソッドは、待たずにすぐに戻ります。使用しようとしているフラグ手法の感情に非常に近いものです。Monitor.TryEnterTimeSpan

于 2011-12-28T05:32:02.287 に答える
1

制限が1でタイムアウト期間が0ミリ秒のセマフォが必要です

セマフォを使用することで、一度に1つのコードにアクセスできるスレッドの数は限られていると言えます。

使用方法については、このサンプルを参照してください

待つにはこの方法を使う必要があります

bool WaitOne(int millisecondsTimeout)

タイムアウト期間=0を指定します。このようにして、待機中のスレッドは0秒間待機します。つまり、コードをスキップするだけです。

class SemaphoreExample    
{ 
// Three reserved slots for threads
public static Semaphore Pool = new Semaphore(1, 0);

public static void Main(string[] args) 
{    
// Create and start 20 threads    
for (int i = 0; i < 20; i++) 
{ 
    Thread t = new Thread(new ThreadStart(DoWork)); 
    t.Start(); 
}

Console.ReadLine();    
}

private static void DoWork()    
{    
// Wait 0 miliseconds  
SemaphoreExample.Pool.WaitOne(0);


#region Area Protected By Semaphore    
Console.WriteLine("Acquired slot...");

for (int i = 0; i < 10; i++) 
{   
    Console.WriteLine(i + 1);  
}   
Console.WriteLine("Released slot...");    

#endregion        
// Release the semaphore slot    
SemaphoreExample.Pool.Release();    
}    
}
于 2011-12-28T05:30:27.360 に答える
0

Monitor.TryEnter を使用できます

http://msdn.microsoft.com/en-us/library/dd289679.aspx

于 2011-12-28T05:43:06.977 に答える