51

Java's Object.wait() warns against "spurious wakeups" but C#'s Monitor.wait() doesn't seem to mention it at all.

Seeing how Mono is implemented on top of Linux, and Linux has spurious wakeups, shouldn't this be documented somewhere?

Gray
  • 115,027
  • 24
  • 293
  • 354
Gili
  • 86,244
  • 97
  • 390
  • 689

1 Answers1

90

Joe Duffy's "Concurrent Programming On Windows" mentions this (P311-312, P598). This bit is interesting:

Note that in all of the above examples, threads must be resilient to something called spurious wake-ups - code that uses condition variables should remain correct and lively even in cases where it is awoken prematurely, that is, before the condition being sought has been established. This is not because the implementation will actually do such things (although some implementations on other platforms like Java and Pthreads are known to do so), nor because code will wake threads intentionally when it's unnecessary, but rather due to the fact that there is no guarantee around when a thread that has been awakened will become scheduled. Condition variables are not fair. It's possible - and even likely - that another thread will acquire the associated lock and make the condition false again before the awakened thread has a chance to reacquire the lock and return to the critical region.

He then gives the normal pattern for a while loop testing the condition.

I would say that from this it's reasonable to expect that Monitor.Wait won't normally wake you prematurely, and that if you absolutely know that nothing else can have changed the condition then you might be able to get away without the condition loop: but that it's safer to include it anyway, just in case your logic is inaccurate.

Jon Skeet
  • 1,421,763
  • 867
  • 9,128
  • 9,194
  • 2
    I'm checking with Joe directly to see if my extrapolation is correct. – Jon Skeet Sep 22 '09 at 19:06
  • Did Joe get back to you on that? On Page 207 of the same book he states that the CLR uses a common (alertable) waiting routine any time you block, including blocking calls to Monitor. Would this imply that in addition to the 'apparent' spurious wakeups you mention, your Wait could also be subject to a 'genuine' supirous wakeup caused by an Asynchronous Procedure Call? – Daniel Fortunov Feb 03 '10 at 07:35
  • 3
    Except... in *Java* on Windows 2000, XP and 7 I have absolutely demonstrated that spurious wakeups do occur, and the reason is probably hardware - it's unlikely (but not impossible) that C# is able to avoid this where Java cannot. – Lawrence Dol May 01 '13 at 04:13
  • @SoftwareMonkey: Well I'd definitely "do the right thing" and assume it *might* happen - but I don't think I've ever seen it myself. Will edit a little. – Jon Skeet May 01 '13 at 05:22
  • 2
    Now that's interesting, and confusing. Two different concepts seems to be put under the same moniker "spurious wakeup". Really spurious: "awoken [...] before the condition being sought has been established". Kind of oversleep: scheduled after the condition was falsified again. If a scheduler could equate "awoken" with "scheduled", this second issue would vanish. – YvesgereY Aug 07 '17 at 16:49
  • 3
    [This short article by Raymond Chen](https://blogs.msdn.microsoft.com/oldnewthing/20180201-00/?p=97946) states that spurious wakeups are a thing in Win32 conditional variables. Based on his description of the causes, it implies to me that these conditions (stolen wakeups, overwaking) are likely a part of similar Win32 sync mechanisms. – Kent Jul 09 '18 at 21:06