C#等待所有线程发出信号后再继续

C#等待所有线程发出信号后再继续,c#,multithreading,synchronization,C#,Multithreading,Synchronization,我正在编写一个C#程序,它涉及多线程和多线程之间的同步。所有线程都需要独立地执行一些迭代工作,在某个线程完成指定数量的迭代后,它必须等待其他线程出现。在它们完成给定数量的迭代并获得一些中间结果之后,它们应该执行一些同步工作,然后再次继续执行,直到到达另一个同步点,依此类推 下面是我的尝试(一个线程应该在一次迭代后暂停,然后等待其他线程): int-nThreads=Environment.ProcessorCount; 线程[]线程=新线程[n线程]; ManualResetEvent[]man

我正在编写一个C#程序,它涉及多线程和多线程之间的同步。所有线程都需要独立地执行一些迭代工作,在某个线程完成指定数量的迭代后,它必须等待其他线程出现。在它们完成给定数量的迭代并获得一些中间结果之后,它们应该执行一些同步工作,然后再次继续执行,直到到达另一个同步点,依此类推

下面是我的尝试(一个线程应该在一次迭代后暂停,然后等待其他线程):

int-nThreads=Environment.ProcessorCount;
线程[]线程=新线程[n线程];
ManualResetEvent[]manualResetEvents=新的ManualResetEvent[n读取];
对于(int i=0;i0)
{
manualResetEvents[idx].Reset();
Write(“\nThread{0}正在工作…cStep={1}\n”,idx,cStep);
线程睡眠(rnd.Next(1000));
manualResetEvents[idx].Set();
WriteLine(“\nThread{0}工作已完成。正在等待其他人…cStep={1}\n”,idx,cStep);
WaitHandle.WaitAll(手动重置事件);
cStep--;
}
});
}
对于(int i=0;i

但是上面的代码似乎不起作用,因为没有任何线程出于某种原因等待所有其他线程执行一次迭代。我想我误解了ManualResetEvent的目的,或者使用了错误的方法,您有什么建议?

您的代码容易出现争用情况。在所有线程完成第一次迭代后,仍然设置所有事件;如果一个线程在其他线程重置其事件之前在循环中运行,那么它将看到其他事件仍然被设置,并提前停止等待


有很多方法可以解决这个bug,但对您来说最好的解决方案是
System.Threading.Barrier
。它是专门为这种情况设计的,在这种情况下,您需要多个线程通过多步算法并行工作。

非常感谢您的帮助,我已经使用前面提到的Barrier类解决了这个问题。
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();
}