2016-12-14 135 views
1

我在寫一個涉及多線程和多線程間同步的C#程序。線程都需要獨立地執行一些迭代工作,並且在某個線程完成了指定次數的迭代之後,它必須等待其他線程出現。完成所有迭代並獲得一些中間結果後,它們應該執行一些同步工作,然後再繼續執行,直到達到另一個同步點爲止。C#等待來自所有線程的信號,然後再繼續

這裏是我試圖做到這一點(線程只是一個迭代後應暫停,然後等待其他人):

int nThreads = Environment.ProcessorCount; 
Thread[] threads = new Thread[nThreads]; 

ManualResetEvent[] manualResetEvents = new ManualResetEvent[nThreads]; 
for (int i = 0; i < nThreads; i++) 
{ 
    manualResetEvents[i] = new ManualResetEvent(false); 
} 

int nSteps = 5; 
Random rnd = new Random(); 
for (int i = 0; i < nThreads; i++) 
{ 
    int idx = i; 
    threads[i] = new Thread(delegate() 
    { 
     int cStep = nSteps; 

     while (cStep > 0) 
     { 
      manualResetEvents[idx].Reset(); 
      Console.Write("\nThread {0} working... cStep = {1}\n", idx, cStep); 

      Thread.Sleep(rnd.Next(1000)); 

      manualResetEvents[idx].Set(); 
      Console.WriteLine("\nThread {0} work done. Waiting Others...cStep = {1}\n", idx, cStep); 

      WaitHandle.WaitAll(manualResetEvents); 
      cStep--; 
     } 

    }); 
} 

for (int i = 0; i < nThreads; i++) 
{ 
    threads[i].Start(); 

} 

for (int i = 0; i < nThreads; i++) 
{ 
    threads[i].Join(); 
} 

但上面的代碼出現不工作,不任何線程等待所有其他線程的由於某種原因執行一次迭代。我想我誤解了ManualResetEvent的用途或以錯誤的方式使用它,您能提出什麼建議?

回答

2

您的代碼容易出現競爭狀況。在所有線程完成第一次迭代後,所有事件仍然被設置;如果單個線程在其他人重置事件之前通過循環運行,則會看到其他事件仍然設置,並提前停止等待。

有很多方法可以解決這個錯誤,但最適合您的解決方案是System.Threading.Barrier。它明確地設計用於這種情況,您希望多個線程通過多步算法並行工作。

+0

非常感謝您的幫助,我已經使用提到的Barrier類解決了這個問題。 – user3808059

相關問題