Monitor.Pulse和Monitor.PulseAll之间的区别

Mic*_*ndl 27 .net c# multithreading

Monitor.PulseAll通知队列中的所有等待线程.

Monitor.Pulse通知等待队列中的线程.(下一个等待线程)

只有下一个线程(一个线程)才能获得锁定.那么区别是什么呢?

我何时应该使用Pulsevs PulseAll

Jon*_*eet 44

使用PulseAll时,你要唤醒多个线程,因为他们正在等待条件现在可以实现对多个线程.(等待几乎总是与条件相关 - 您通常应该在while循环中测试该条件.)

使用Pulse时,你只需要唤醒一个线程,因为只有一个线程实际上能够做无用功.

给出两个类比:

想象一下,你有一台打印机.一次只有一个人可以使用它,所以如果你有很多人在等待,你就把它们全部送去睡觉了 - 但是当打印机空闲时你只会唤醒一个人.这反映了使用Pulse.

现在想象你经营一家商店.当您关闭时,客户会在商店外等候.当你开店时,你不仅要唤醒一个顾客 - 他们现在都可以进来.这反映了使用PulseAll.

  • "当调用PulseAll的线程释放锁时,就绪队列中的下一个线程将获得锁定." - 如果我一次只能处理一个客户 - 为什么我应该唤醒所有人? (3认同)

Jim*_*hel 36

A Monitor有两个队列:等待队列和就绪队列.在没有Wait和的情况下Pulse,尝试获取锁的所有线程都进入就绪队列.当锁定可用时,就绪队列中的一个线程将获取它.

当一个线程获得锁定然后执行a时Wait,该线程进入等待队列.它正在等待一个PulsePulseAll,并且将保持在等待队列中,直到它收到一个Pulse,即使来自就绪队列的其他线程获取并释放锁定.

Pulse将一个线程从等待队列移动到就绪队列. PulseAll将所有线程从等待队列移动到就绪队列.

这里的关键是等待队列中的线程永远不能获取锁.他们正在等待一个脉冲将它们移回就绪队列,这样他们就可以获得锁定.

对Wait和Pulse有一个相当不错的讨论 - 至少有一点让你开始 - 在这里.

  • @RamiYampolsky:执行`Pulse`的线程保留了锁定.它必须调用`Wait`或`Exit`来释放锁,然后就绪队列中的下一个线程才能获得锁. (3认同)
  • 非常清晰的描述。谢谢。 (2认同)