sync.Cond and spurious wekeups

531 views
Skip to first unread message

Dmitry Vyukov

unread,
Feb 17, 2012, 1:25:42 AM2/17/12
to golang-dev
Don't we want to explicitly say that spurious wakeups are all allowed for sync.Cond?
Rationale:
Both POSIX and Win32 condvars explicitly allow spurious wakeups. So it's established for decades practice to always surround Cond.Wait() with a loop, it may be confusing for some people to see code w/o the loop. Potentially it may prevent some bugs - we will say that the loop is always required around Wait(), so it may prevent some day 1 bugs (when a user does not fully understand all implications of concurrency), or prevent bugs during code evolution (initially the loop was not required, but become required after some changes). As for performance, the loop should not cause significant degradation (expensive to calculate wait predicates?); potentially it will allow us to use more efficient condvar algorithms in the future.




David Symonds

unread,
Feb 17, 2012, 1:31:44 AM2/17/12
to Dmitry Vyukov, golang-dev
On Fri, Feb 17, 2012 at 5:25 PM, Dmitry Vyukov <dvy...@google.com> wrote:

> Don't we want to explicitly say that spurious wakeups are all allowed for
> sync.Cond?

How hard would it be to make the Go primitives not need this? I don't
know of any situation where a programmer wants a spurious wakeup; they
are an implementation artifact exposed to users.


Dave.

Russ Cox

unread,
Feb 17, 2012, 1:34:14 AM2/17/12
to Dmitry Vyukov, golang-dev
The Cond.Wait comment does point out that you need to use a loop.

Scott Lawrence

unread,
Feb 17, 2012, 1:34:45 AM2/17/12
to David Symonds, Dmitry Vyukov, golang-dev

I think it's worth pointing out (as I did previously), that this
implementation artifact is not, in fact, exposed to users in any go
implementation that uses sync.Cond from the standard library. It's built on
Semacquire, which does not permit spurious interrupts.

Since we don't /have/ spurious wakeups, I rather think that's something to
flaunt, and definitely not hide.

--
Scott Lawrence

Dmitry Vyukov

unread,
Feb 17, 2012, 1:39:12 AM2/17/12
to David Symonds, golang-dev
I think the current implementation does not produce spurious wakeups. So we can leave the docs as is, if it is deliberate.

David Symonds

unread,
Feb 17, 2012, 1:39:57 AM2/17/12
to Dmitry Vyukov, golang-dev

Note that this doesn't mean one should never put a loop around Wait;
if you're waiting on a var become a particular value, and the thing
changing that var does a Broadcast after changing it to a number of
different values, you still obviously want to loop until the var
becomes the specific value you want. But, in the simplest case of a
latch mechanism, spurious wakeups are just a nuisance.


Dave.

Dmitry Vyukov

unread,
Feb 17, 2012, 1:40:21 AM2/17/12
to Scott Lawrence, David Symonds, golang-dev
That's one possible option. I just want the decision to be deliberate.
 

David Symonds

unread,
Feb 17, 2012, 1:41:20 AM2/17/12
to Dmitry Vyukov, golang-dev

Maybe it should be explicitly documented that spurious wakeups won't
occur, then. Programmers coming from other systems may assume that
they do.


Dave.

Dmitry Vyukov

unread,
Feb 17, 2012, 1:42:35 AM2/17/12
to r...@golang.org, golang-dev
On Fri, Feb 17, 2012 at 10:34 AM, Russ Cox <r...@golang.org> wrote:
The Cond.Wait comment does point out that you need to use a loop.

No, it is not. It says that I need the loop iff another goroutine can consume the event or signaler does 'over-signalling'.

Dmitry Vyukov

unread,
Feb 17, 2012, 1:43:32 AM2/17/12
to David Symonds, golang-dev
On Fri, Feb 17, 2012 at 10:41 AM, David Symonds <dsym...@golang.org> wrote:
>> > Don't we want to explicitly say that spurious wakeups are all allowed
>> > for
>> > sync.Cond?
>>
>> How hard would it be to make the Go primitives not need this? I don't
>> know of any situation where a programmer wants a spurious wakeup; they
>> are an implementation artifact exposed to users.
>
>
> I think the current implementation does not produce spurious wakeups. So we
> can leave the docs as is, if it is deliberate.

Maybe it should be explicitly documented that spurious wakeups won't
occur, then. Programmers coming from other systems may assume that
they do.


Just wanted to say the same. I think it is the best solution.

cherr...@gmail.com

unread,
Aug 15, 2016, 2:10:02 PM8/15/16
to golang-dev, dsym...@golang.org
I have implemented a semaphore demo using sync.Cond. It seems that  spurious wakeups did occur when testing benchmark. 
Maybe there is something wrong with my code? ( https://play.golang.org/p/mhcQspETZY , tested both on OSX and Linux)

在 2012年2月17日星期五 UTC+8下午2:43:32,Dmitry Vyukov写道:

Ian Lance Taylor

unread,
Aug 15, 2016, 3:28:28 PM8/15/16
to cherr...@gmail.com, golang-dev, David Symonds
On Mon, Aug 15, 2016 at 10:27 AM, <cherr...@gmail.com> wrote:
> I have implemented a semaphore demo using sync.Cond. It seems that spurious
> wakeups did occur when testing benchmark.
> Maybe there is something wrong with my code? (
> https://play.golang.org/p/mhcQspETZY , tested both on OSX and Linux)

Your test does not test whether there is a spurious Signal. There can
be a simultaneous Signal due to a Release and an Acquire due to the
benchmarking loop. In such a case the new Acquire will see s.sem ==
0, and increment s.sem. The signaled Acquire has no further
condition, and will also increment s.sem.

Ian

Cherrot Luo

unread,
Aug 15, 2016, 10:42:17 PM8/15/16
to Ian Lance Taylor, golang-dev, David Symonds
Ahh.. Indeed it is. Now I know why the document suggests invoking Wait() in a loop.

Forgive me for such a silly question  :D

Ian Lance Taylor <ia...@golang.org>于2016年8月16日周二 上午3:28写道:
--
You received this message because you are subscribed to a topic in the Google Groups "golang-dev" group.
To unsubscribe from this topic, visit https://groups.google.com/d/topic/golang-dev/Kc1nOjju3zk/unsubscribe.
To unsubscribe from this group and all its topics, send an email to golang-dev+...@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.
Reply all
Reply to author
Forward
0 new messages