2016-12-14 1 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

관련 문제