Monitor.Pulse和 PulseAll 要求它操作的锁在调用时被锁定。这个要求似乎是不必要的并且对性能有害。我的第一个想法是这会导致 2 次浪费的上下文切换,但下面的 nobugz 已对此进行了纠正(谢谢)。我仍然不确定它是否涉及浪费上下文切换的可能性,因为在监视器上等待的其他线程已经可用于调度程序,但是如果它们被调度,它们将只能运行一些指令在击中互斥体之前,必须再次进行上下文切换。如果在调用 Monitor.Pulse之前解锁锁,这看起来会更简单、更快。
pthread 条件变量实现了相同的概念,但它没有上述限制:即使您不拥有互斥锁,也可以调用 pthread_cond_broadcast。我认为这是证明该要求不合理的证据。
编辑:我意识到需要一个锁来保护通常在 Monitor.Pulse 之前更改的共享资源。我想说的是,在访问资源之后但在 Pulse 之前,该锁可能已经解锁,因为 Monitor 会支持这一点。这将有助于将锁定限制在访问共享资源的最短时间。像这样:
void f(Item i)
{
lock(somequeue) {
somequeue.add(i);
}
Monitor.Pulse(somequeue); // error
}