2017-11-27 4 views
-1

ロックされたスレッドのいずれかが通過して何らかのタスクを完了した後、すべてのスレッドを解放したいと考えています。私が何をしたいかについてのサンプルコードを投稿しましょう。重要なのは、最初のスレッドが自分の仕事を完了した後、すべてを一緒に通過しなければならないということです。彼らは(残りの99スレッド)は、決して1つ1つを通過してロックされていないようにする必要があります。すべてのロックされたスレッドを解放する

  Monitor.Enter(_lock);//imagine 100x threads hit this lock at same time. 
     //1 thread pass there 
     if (data == null) 
     { 
      data = GetData(); 
     } 

     Monitor.Exit(_locker);//one more thread allow after this code.And they all come one by one in order.In these point I want to release them all together. 

私はモニター、ミューテックス、セマフォ、ReadWriteLock、ManaualResetEventなどのようなスレッドが、私はこれを行うために管理していなかった程度のクラスの多くを試してみましたが、それらはすべて一つずつ来ます。あなたはこれをやったことがありますか?または、あなたはそれについてアリの考えを持っていますか?私はそれにもっと時間を費やしたくない。

答えて

0

これが最も効率的な方法ではないかもしれませんが、それは動作します:

static SemaphoreSlim semaphore = new SemaphoreSlim(1, 1); 
static CancellationTokenSource cts = new CancellationTokenSource(); 
static void CriticalSection() 
{ 
    if(!cts.Token.IsCancellationRequested) 
    { 
     try 
     { 
      semaphore.Wait(cts.Token); 
     } 
     catch (OperationCanceledException) { } 
    } 
    /* 
    Critical section here 
    */ 
    if(!cts.Token.IsCancellationRequested) 
     cts.Cancel(); 
} 

SemaphoreSlimは1つのだけのスレッドが「クリティカルセクション」を実行できるようになります。最初のスレッドがセクションの上に来たら、それはトークンを取り消します。これにより、hereのようにOperationCanceledExceptionが発生します。待機していたすべてのスレッドは、「try catchステートメント」でキャッチされた例外をスローし、クリティカルセクションを実行します。最初の "if文"は、トークンの状態をチェックして、過去にキャンセルされている場合は待機とスローパターンを回避することです。

パフォーマンスヒットは、スレッドがすべて「例外」をスローするため、待機から「解放」されたときに初めて発生します。後で、唯一の影響は、キャンセルトークンチェックとコードの一般的な保守性の周りにあることになります。

+0

このコードでは、CTSがキャンセルされると、すべての呼び出し元がクリティカルセクションを実行します。 – Servy

+0

@Servyは、OPが求めているものとまったく同じではありませんか? – Daneau

+0

値は*正確に1回構築する必要があります。 – Servy

-2
static SemaphoreSlim semaphore = new SemaphoreSlim(1); 

    static void Main(string[] args) 
    { 
     for (int i = 0; i < 10; i++) 
     { 
      Thread t = new Thread(LoadDataPart); 
      t.Name = (i + 1).ToString(); 
      t.Start(); 
     } 

     Console.Read(); 
    } 

    static void LoadDataPart() 
    { 


     Console.WriteLine("Before Wait {0}", Thread.CurrentThread.Name); 
     semaphore.Wait(); 
     Console.WriteLine("After Wait {0}", Thread.CurrentThread.Name); 
     Thread.Sleep(3000); 
     Console.WriteLine("Done {0}", Thread.CurrentThread.Name); 

     semaphore.Release(10);//this line must be changed,its allow too much thread coz its called 10 times! 

    } 

このようにしたいことを管理できます。このコードでは、10個のスレッドが待機します。彼らのうち9人は他の人が続けるのを待った。 1つの糸が彼の仕事を終えると、他の9人は一緒に行くのではなく、一緒に行く。私がスレッドスリープを入れ、すべてのスレッドが30秒で6秒で複雑になっていることを確認する。これでコードをカスタマイズできます。

+0

このアプローチにはいくつかの欠陥があります。予想されるスレッドの正確な数がわからない限り、semaphore.Release(x)はあなたの質問の "すべてを一緒に渡す必要がある"部分を許可しません。この場合、スレッド数が少なく、スレッド数と同じ数を正確に解放し、「criticalsection」がそれを長く取っていないために動作しています。また、サンプルで指摘されているようにセマフォ数を頻繁に増やします。 – Daneau

+0

@Daneauはい私はこの問題に気付きました。たぶん私は何とかそれを使用することができますが、その正確なソリューションのように見えません。私はそれを行うhealty方法がないと思う。 – Math1

関連する問題