简体   繁体   English

C#等待来自所有线程的信号,然后继续

[英]C# Wait for signals from all the threads before proceed

I'm writing a C# program which involves multithreading and synchronization between multiple threads. 我正在编写一个C#程序,其中涉及多线程和多个线程之间的同步。 The threads all need perform some iterative work independently, and after some thread has finished a specified number of iterations, it must wait for the other threads to come up. 所有线程都需要独立执行一些迭代工作,并且在某个线程完成指定次数的迭代之后,它必须等待其他线程出现。 After all of them have finished given number of iterations and obtained some intermediate result, they should do some synchronized work and then continue execution again, until another synchronization point is reached and so on. 它们全部完成给定的迭代次数并获得一些中间结果后,它们应该执行一些同步的工作,然后再次继续执行,直到到达另一个同步点,依此类推。

Here's my attempt to achieve this (a thread should pause after just one iteration, then wait for the others): 这是我尝试实现的目标(一个线程应该在一个迭代之后暂停,然后等待其他迭代):

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();
}

But the code above appears not working, for not any thread waits for all of the other threads to perform one iteration for some reason. 但是上面的代码似乎不起作用,因为出于某种原因,没有任何线程等待所有其他线程执行一次迭代。 I think I misunderstand the purpose of ManualResetEvent or use it the wrong way, what could you suggest? 我认为我误解了ManualResetEvent的目的或使用了错误的方式,您有何建议?

Your code is prone to race conditions. 您的代码容易出现竞争状况。 After all threads have completed the first iteration, all events are still set; 在所有线程完成第一次迭代之后,仍将设置所有事件。 if a single thread then runs through the loop before the others get to reset their events, it'll see the other events still set, and stop waiting early. 如果单个线程在其他线程重置其事件之前先运行了循环,则它将看到其他事件仍在设置,并尽早停止等待。

There's plenty of ways to resolve this bug, but the best solution for you is System.Threading.Barrier . 有很多方法可以解决此错误,但最适合您的解决方案是System.Threading.Barrier It's explicitly designed for this situation, where you want multiple threads to work in parallel through a multi-step algorithm. 它是专门针对这种情况而设计的,在这种情况下,您希望多个线程通过多步算法并行工作。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM