我正在阅读 MSDN 上的 AutoResetEvent 文档,并且以下警告让我很困扰..
“重要:不能保证每次调用Set方法都会释放一个线程。如果两个调用靠得太近,以至于第二个调用发生在一个线程被释放之前,那么只有一个线程被释放。就好像“
但是这个警告基本上扼杀了拥有这种线程同步技术的理由。例如,我有一个可以容纳工作的列表。而且只有一个生产者会将工作添加到列表中。我有消费者(不止一个),等待从列表中获得工作.. 像这样..
制片人:
void AddJob(Job j)
{
lock(qLock)
{
jobQ.Enqueue(j);
}
newJobEvent.Set(); // newJobEvent is AutoResetEvent
}
消费者
void Run()
{
while(canRun)
{
newJobEvent.WaitOne();
IJob job = null;
lock(qLock)
{
job = jobQ.Dequeue();
}
// process job
}
}
如果上述警告属实,那么如果我很快将两个作业排入队列,那么只有一个线程会接手该作业,不是吗?我假设 Set 将是原子的,即它执行以下操作:
- 设置事件
- 如果线程正在等待,则选择一个线程唤醒
- 重置事件
- 运行选定的线程。
所以我基本上对 MSDN 中的警告感到困惑。这是一个有效的警告吗?