C#Monitor.Wait()是否遭受虚假唤醒?

Gil*_*ili 45 c# java multithreading

Java的Object.wait()警告"虚假的唤醒",但C#的Monitor.wait()似乎根本没有提到它.

看看Mono是如何在Linux之上实现的,并且Linux有虚假的唤醒,不应该在某处记录吗?

Jon*_*eet 78

Joe Duffy的"Windows上并发编程"提到了这一点(P311-312,P598).这一点很有趣:

请注意,在上述所有示例中,线程必须对称为虚假唤醒的内容具有弹性 - 即使在过早唤醒的情成立.这不是因为实现实际上会做这样的事情(虽然已知其他平台上的某些实现,比如Java和Pthreads这样做),也不是因为代码会在不必要时故意唤醒线程,而是因为没有保证被唤醒的线程何时被安排.条件变量不公平.有可能 - 甚至可能 - 另一个线程将获取相关的锁并在唤醒的线程有机会重新获取锁并返回临界区之前再次使条件成为假.

然后他给出了测试条件的while循环的正常模式.

我会说从这里可以合理地预期通常Monitor.Wait 不会过早地唤醒你,并且如果你完全知道没有别的东西可以改变条件,那么你可以在没有条件循环的情况下逃脱:但它更安全无论如何要包括它,以防你的逻辑不准确.

  • 我正在直接与乔核实,看看我的推断是否正确。 (2认同)
  • 除了...在 Windows 2000、XP 和 7 上的 *Java* 中,我已经完全证明确实会发生虚假唤醒,原因可能是硬件 - C# 不太可能(但并非不可能)在 Java 无法避免的情况下避免这种情况。 (2认同)
  • 现在,这很有趣并且令人困惑。在同一个绰号“虚假唤醒”下似乎有两个不同的概念。真正的虚假:“在确定要寻求的条件之前就被唤醒”。有点睡过头:计划在病情再次被伪造之后。如果调度程序可以将“已唤醒”与“已调度”等同,则第二个问题将消失。 (2认同)
  • [Raymond Chen的这篇简短文章](https://blogs.msdn.microsoft.com/oldnewthing/20180201-00/?p=97946)指出,虚假唤醒是Win32条件变量中的一件事。根据他对原因的描述,向我暗示这些情况(被盗的唤醒,唤醒)可能是类似Win32同步机制的一部分。 (2认同)