繁体   English   中英

等待信号量的正确方法是什么?

[英]What's the proper way to wait on a Semaphore?

我认为以下代码会让所有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传递给每个线程,然后在那些EventWaitHandles的数组上执行WaitAll() ,那么在一个数组上执行WaitAll()的含义是什么一个信号量? 换句话说,等待线程何时解除阻塞?

WaitHandle.WaitAll只是等待所有处理程序都处于信号状态。

因此,当您在一个 WaitHandle.WaitAllWaitHandle它的工作方式与调用s.WaitOne()

例如,您可以使用以下代码等待所有已启动的线程,但允许两个线程并行运行:

int count = 0;

Semaphore s = new Semaphore(2, 2);
AutoResetEvent[] waitHandles = new AutoResetEvent[10];
for (int x = 0; x < 10; x++)
    waitHandles[x] = new AutoResetEvent(false);

for (int x = 0; x < 10; x++)
{
    Thread t = new Thread(threadNumber =>
        {
            s.WaitOne();
            Thread.Sleep(1000);
            Interlocked.Increment(ref count);
            waitHandles[(int)threadNumber].Set();
            s.Release();
        });
    t.Start(x);
}

WaitHandle.WaitAll(waitHandles);
Console.WriteLine("done: {0}", count);

WaitHandle.WaitAll(new WaitHandle[] { s }); 等待s.WaitOne(); 它在第一次机会进入。 您似乎希望此调用等待所有其他信号量操作,但操作系统无法区分它们。 此命令可能是第一个被授予访问信号量的命令。

我认为你需要的是Barrier课程。 它用于fork-join-style并行。

暂无
暂无

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

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