我原以为以下代码会让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()
有何意义呢?换句话说,等待线程何时解除阻塞?
Console.WriteLine
周围有它自己的锁,输出内容的顺序不能保证与调用顺序相同。你可能想要编写滴答值或使用一个处理这种情况更好的日志框架。输出并不表明两个线程没有同时运行两个任务。 - casperOneInterlocked.Increment
而不是volatile
: https://dev59.com/VHVC5IYBdhLWcg3w4Vb6 - Chris SinclairThread
对象并依次在每个对象上调用Join
方法。 - Jon