首页 文章

C#在继续之前等待来自所有线程的信号

提问于
浏览
1

我正在编写一个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的目的或以错误的方式使用它,你能提出什么建议?

1 回答

  • 2

    您的代码很容易出现竞争条件 . 在所有线程完成第一次迭代后,仍然设置所有事件;如果一个线程然后在其他人重置他们的事件之前运行循环,它将看到其他事件仍然设置,并且提前停止等待 .

    有很多方法可以解决这个问题,但最适合您的解决方案是 System.Threading.Barrier . 它是针对这种情况明确设计的,您希望多个线程通过多步算法并行工作 .

相关问题