【发布时间】:2026-02-23 08:00:01
【问题描述】:
我认为下面的代码会让所有 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(),那么执行@ 的含义是什么987654328@ 在只有一个信号量的数组上?也就是说,等待线程什么时候解除阻塞?
【问题讨论】:
-
您很可能会看到本地化的竞争条件;
Console.WriteLine有它自己的锁,输出内容的顺序不能保证是你调用它的顺序。您可能想要编写刻度值或使用更好地处理这种情况的日志框架。输出没有显示两个线程没有同时运行两个线程。 -
仅供参考,您可能需要考虑使用
Interlocked.Increment而不是volatile:*.com/questions/154551/… -
casperOne,我不确定这是否正确,因为即使我将最后一行替换为 System.Diagnostics.Debug.WriteLine("done"); 也会遇到同样的问题;
-
我不太确定这个例子的意义是什么——反正你要启动 10 个线程。如果你想一次运行两个线程,为什么不只打开两个线程并平均分配工作。
-
如果您想等待所有线程完成,请保留
Thread对象并依次调用每个对象上的Join。
标签: c# .net multithreading semaphore waithandle