FAQ
In short: I have a for loop containing a select statement with a receive
clause (which just consumes the value) and a default clause (which exits
the loop). The goal is to drain a channel of all items.

There are several goroutines that are blocked on sending to the channel (it
has a small capacity, but there are many more senders).

My confusion is about the implementation of the default branch of select.

I was expecting that when the receive clause ran out of items to read from
the channel, instead of going down the default clause, we would fire up
some of the routines blocked on sending to the channel.

See http://play.golang.org/p/iO9M9FLDWw which exits after 10 values, rather
than the 100 I had expected.

If instead I replace the default case by a timer, I see my expected
behavior.

http://play.golang.org/p/71VkFs2F1K

Can someone with more experience than me in the language design explain the
rationale of the default branch evaluation, and also weigh in on whether
there is a better solution than a timer?

Thanks!

-- johan

--
You received this message because you are subscribed to the Google Groups "golang-nuts" group.
To unsubscribe from this group and stop receiving emails from it, send an email to golang-nuts+unsubscribe@googlegroups.com.
For more options, visit https://groups.google.com/groups/opt_out.

Search Discussions

  • Dave Cheney at Sep 11, 2013 at 1:58 am
    I suggest using a sync.WaitGroup, http://play.golang.org/p/wi9F5pjl4_
    On Wed, Sep 11, 2013 at 6:48 AM, Johan Ovlinger wrote:

    In short: I have a for loop containing a select statement with a receive
    clause (which just consumes the value) and a default clause (which exits the
    loop). The goal is to drain a channel of all items.

    There are several goroutines that are blocked on sending to the channel (it
    has a small capacity, but there are many more senders).

    My confusion is about the implementation of the default branch of select.

    I was expecting that when the receive clause ran out of items to read from
    the channel, instead of going down the default clause, we would fire up some
    of the routines blocked on sending to the channel.

    See http://play.golang.org/p/iO9M9FLDWw which exits after 10 values, rather
    than the 100 I had expected.

    If instead I replace the default case by a timer, I see my expected
    behavior.

    http://play.golang.org/p/71VkFs2F1K

    Can someone with more experience than me in the language design explain the
    rationale of the default branch evaluation, and also weigh in on whether
    there is a better solution than a timer?

    Thanks!

    -- johan

    --
    You received this message because you are subscribed to the Google Groups
    "golang-nuts" group.
    To unsubscribe from this group and stop receiving emails from it, send an
    email to golang-nuts+unsubscribe@googlegroups.com.
    For more options, visit https://groups.google.com/groups/opt_out.
    --
    You received this message because you are subscribed to the Google Groups "golang-nuts" group.
    To unsubscribe from this group and stop receiving emails from it, send an email to golang-nuts+unsubscribe@googlegroups.com.
    For more options, visit https://groups.google.com/groups/opt_out.
  • Jesse McNelis at Sep 11, 2013 at 2:45 am

    On Wed, Sep 11, 2013 at 6:48 AM, Johan Ovlinger wrote:

    I was expecting that when the receive clause ran out of items to read from
    the channel, instead of going down the default clause, we would fire up
    some of the routines blocked on sending to the channel.
    See http://play.golang.org/p/iO9M9FLDWw which exits after 10 values, rather
    than the 100 I had expected.

    If instead I replace the default case by a timer, I see my expected
    behavior.

    http://play.golang.org/p/71VkFs2F1K

    Can someone with more experience than me in the language design explain
    the rationale of the default branch evaluation, and also weigh in on
    whether there is a better solution than a timer?
    It looks like you're trying to sync without blocking. This will end in race
    condition pain.
    You should be using a 'for range' loop to receive on that channel to wait
    for it to be closed.
    You can have another goroutine waiting on a sync.WaitGroup to close the
    channel when all the senders are done.

    Now you're syncing by blocking and the races go away.
    http://play.golang.org/p/F1vJ33aq5B

    --
    You received this message because you are subscribed to the Google Groups "golang-nuts" group.
    To unsubscribe from this group and stop receiving emails from it, send an email to golang-nuts+unsubscribe@googlegroups.com.
    For more options, visit https://groups.google.com/groups/opt_out.
  • Johan Ovlinger at Sep 11, 2013 at 3:35 pm
    Jesse, Dave,

    thanks for the replies. Very informative.
    On Tue, Sep 10, 2013 at 10:45 PM, Jesse McNelis wrote:


    It looks like you're trying to sync without blocking. This will end in
    race condition pain.
    I'm actually trying to just unblock all goroutines that are blocked on
    writing to a channel that is about to be closed.

    You should be using a 'for range' loop to receive on that channel to wait
    for it to be closed.
    You can have another goroutine waiting on a sync.WaitGroup to close the
    channel when all the senders are done.
    The problem is that I really won't know how many senders there are (ie, the
    for loop of 0..n to attempt to send to the channel is external to what I am
    writing). However, if move the wg.Add inside each goroutine

    http://play.golang.org/p/NVOjDyQusc

    then I get the behavior I would like to see.

    Thanks for the pointers!

    --
    You received this message because you are subscribed to the Google Groups "golang-nuts" group.
    To unsubscribe from this group and stop receiving emails from it, send an email to golang-nuts+unsubscribe@googlegroups.com.
    For more options, visit https://groups.google.com/groups/opt_out.

Related Discussions

Discussion Navigation
viewthread | post
Discussion Overview
groupgolang-nuts @
categoriesgo
postedSep 11, '13 at 1:47a
activeSep 11, '13 at 3:35p
posts4
users3
websitegolang.org

People

Translate

site design / logo © 2022 Grokbase