C# 什么';等待信号灯的正确方式是什么?
我认为下面的代码将让所有10个线程运行,一次运行两个线程,然后在调用C# 什么';等待信号灯的正确方式是什么?,c#,.net,multithreading,semaphore,waithandle,C#,.net,Multithreading,Semaphore,Waithandle,我认为下面的代码将让所有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()
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);
如果实现我正在寻找的功能的唯一方法是将一个EventWaitHandle
传递给每个线程,然后对这些EventWaitHandles
数组执行一个WaitAll()
,那么对一个只有信号量的数组执行WaitAll()
有什么意义?换句话说,等待线程何时解除阻塞?WaitHandle.WaitAll(新的WaitHandle[]{s})代码>像s.WaitOne()一样等待代码>。它一有机会就进入。您似乎期望此调用等待所有其他信号量操作,但操作系统无法区分这两者之间的区别。这个命令很可能是第一个被授权访问信号量的命令
我想你需要的是屏障
类。它是为fork-join样式的并行而设计的。WaitHandle.WaitAll
只是等待,直到所有处理程序都处于信号状态
因此,当您在one上调用WaitHandle.WaitAll
WaitHandle
时,它的工作原理与调用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);
int count=0;
信号量s=新信号量(2,2);
AutoResetEvent[]waitHandles=新的AutoResetEvent[10];
对于(int x=0;x<10;x++)
waitHandles[x]=新的自动重置事件(false);
对于(int x=0;x<10;x++)
{
线程t=新线程(线程编号=>
{
s、 WaitOne();
睡眠(1000);
联锁增量(参考计数);
waitHandles[(int)threadNumber].Set();
s、 释放();
});
t、 启动(x);
}
WaitHandle.WaitAll(waitHandles);
WriteLine(“完成:{0}”,计数);
很可能您看到的是局部竞争条件Console.WriteLine在其周围有自己的锁,并且不能保证内容的输出顺序与调用它的顺序相同。您可能希望编写勾号值或使用更好地处理这种情况的日志框架。输出没有显示两个线程在同一时间两个线程不同时运行。只是FIY,您可能需要考虑使用<代码>互锁。增量< /COD>而不是<代码> Value:CasPRONE,我不确定是否正确,因为我用同样的问题来处理同样的问题,即使我用Studio.CycTys.Debug .WrdWrand替换最后一行。(“完成”);我真的不确定这个例子的要点是什么-反正你要开始10个线程。如果你想一次运行两个线程,为什么不只打开两个线程并平均分配工作。如果你想等待所有线程完成,请保留线程
对象,并依次对每个线程调用连接
。@caesay the Barrier类当然在网上有很多教程,很容易使用。
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);