我认为以下代码将让所有10个线程同时运行,一次运行两个,然后在Release()被调用10次后打印“done”。但这不是发生的事情:

        int count = 0;

        Semaphore s = new Semaphore(2, 2);
        for (int x = 0; x < 10; x++)
        {
            Thread t = new Thread(new ThreadStart(delegate()
            {
                s.WaitOne();
                Thread.Sleep(1000);
                Interlocked.Increment(ref count);
                s.Release();
            }));
            t.Start(x);
        }

        WaitHandle.WaitAll(new WaitHandle[] { s });
        Console.WriteLine("done: {0}", count);

输出:
done: 6

如果要实现我正在寻找的功能的唯一方法是将EventWaitHandle传递给每个线程,然后在这些WaitAll()的数组上执行EventWaitHandles,那么对仅一个信号量的数组执行WaitAll()的含义是什么?换句话说,等待线程何时解除阻塞?

最佳答案

WaitHandle.WaitAll(new WaitHandle[] { s });就像s.WaitOne();一样等待。它是在第一个机会进入的。您似乎希望此调用能够等待所有其他信号量操作,但是操作系统无法分辨出这种区别。该命令很可能是第一个被授予对信号量访问权限的命令。

我认为您需要的是Barrier类。它是为fork-join风格的并行性而设计的。

10-08 03:19