FAQ
I've somehow managed to put off learning about Go concurrency up until now,
and I'm having some trouble understanding the behavior of buffered channels.

I have a program that is supposed to concurrently spit out values from a
slice into a buffered channel, where they are supposed to be read from and
added together to form a total. The only problem is, it doesn't work.
Here is my code: http://play.golang.org/p/3gKIN_FhFm

What am I doing incorrectly here? I expected the program to create six
goroutines that fill up the channel, and then be able to read from that
channel. The answer should be 73, but I keep getting 18. Thanks for the
help!

--
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/d/optout.

Search Discussions

  • Chris dollin at Jul 9, 2014 at 7:26 am

    On 9 July 2014 08:18, Tyler Compton wrote:

    I've somehow managed to put off learning about Go concurrency up until
    now, and I'm having some trouble understanding the behavior of buffered
    channels.

    I have a program that is supposed to concurrently spit out values from a
    slice into a buffered channel, where they are supposed to be read from and
    added together to form a total. The only problem is, it doesn't work.
    Here is my code: http://play.golang.org/p/3gKIN_FhFm

    What am I doing incorrectly here? I expected the program to create six
    goroutines that fill up the channel, and then be able to read from that
    channel. The answer should be 73, but I keep getting 18. Thanks for the
    help!
    There's only one `val` and when the goroutines read it it's got
    the value `3` (the last value in the list).

    Since updates/reads to `val` happen concurrently, the behaviour
    of the code isn't well-defined anyway. So give each goroutine its
    own freshly-declared val and the problem goes away.

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

    (Runnibng the original code under the race detecttor will probably spot
    the problem.)

    Chris

    --
    Chris "allusive" Dollin

    --
    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/d/optout.
  • Tyler Compton at Jul 9, 2014 at 7:32 am
    Ah, I see. I'm not sure what I was expecting by using the same variable for every goroutine. Thank you for clearing that up!

    --
    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/d/optout.
  • Jsor at Jul 9, 2014 at 7:43 am
    http://play.golang.org/p/Kaba5IerS0

    Common mistake, it's a scoping error-induced race condition. The value
    `val` is the same one from the range clause. What your function is doing is
    this:

    Set val to some value from numSlice
    Start launching the Goroutine
    Set val to next value
    ----> From Goroutine, read val
    Launch Goroutine

    Obviously it may not be that exact loop iteration and that exact Goroutine,
    but that's what's happening, it's reading after val is reset in the loop.
    The fix is to make a copy of the value BEFORE starting the goroutine, and
    send that copy.
    On Wednesday, July 9, 2014 12:18:24 AM UTC-7, Tyler Compton wrote:

    I've somehow managed to put off learning about Go concurrency up until
    now, and I'm having some trouble understanding the behavior of buffered
    channels.

    I have a program that is supposed to concurrently spit out values from a
    slice into a buffered channel, where they are supposed to be read from and
    added together to form a total. The only problem is, it doesn't work.
    Here is my code: http://play.golang.org/p/3gKIN_FhFm

    What am I doing incorrectly here? I expected the program to create six
    goroutines that fill up the channel, and then be able to read from that
    channel. The answer should be 73, but I keep getting 18. Thanks for the
    help!
    --
    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/d/optout.
  • Slawomir Pryczek at Jul 10, 2014 at 1:48 am
    That's interesting actually, as i remember from C that declaration would be
    moved outside of the loop by C optimizer. Actuall that wouldn't probably
    also worked in JS untill you pass the variable to a closure. If i had eg.
    100 million iterations, it'd allocate million copies of locally declared
    variables, or it'd actually move the variable declaration outside of a loop
    untill it "detect" a closure using it is there?

    W dniu środa, 9 lipca 2014 09:43:06 UTC+2 użytkownik Jsor napisał:
    http://play.golang.org/p/Kaba5IerS0

    Common mistake, it's a scoping error-induced race condition. The value
    `val` is the same one from the range clause. What your function is doing is
    this:

    Set val to some value from numSlice
    Start launching the Goroutine
    Set val to next value
    ----> From Goroutine, read val
    Launch Goroutine

    Obviously it may not be that exact loop iteration and that exact
    Goroutine, but that's what's happening, it's reading after val is reset in
    the loop. The fix is to make a copy of the value BEFORE starting the
    goroutine, and send that copy.
    On Wednesday, July 9, 2014 12:18:24 AM UTC-7, Tyler Compton wrote:

    I've somehow managed to put off learning about Go concurrency up until
    now, and I'm having some trouble understanding the behavior of buffered
    channels.

    I have a program that is supposed to concurrently spit out values from a
    slice into a buffered channel, where they are supposed to be read from and
    added together to form a total. The only problem is, it doesn't work.
    Here is my code: http://play.golang.org/p/3gKIN_FhFm

    What am I doing incorrectly here? I expected the program to create six
    goroutines that fill up the channel, and then be able to read from that
    channel. The answer should be 73, but I keep getting 18. Thanks for the
    help!
    --
    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/d/optout.
  • Carlos Castillo at Jul 9, 2014 at 12:27 pm
    In the FAQ: http://golang.org/doc/faq#closures_and_goroutines

    As mentioned on that page, go vet can detect this error. The race detector
    complains about this code as well.
    On Wednesday, July 9, 2014 12:18:24 AM UTC-7, Tyler Compton wrote:

    I've somehow managed to put off learning about Go concurrency up until
    now, and I'm having some trouble understanding the behavior of buffered
    channels.

    I have a program that is supposed to concurrently spit out values from a
    slice into a buffered channel, where they are supposed to be read from and
    added together to form a total. The only problem is, it doesn't work.
    Here is my code: http://play.golang.org/p/3gKIN_FhFm

    What am I doing incorrectly here? I expected the program to create six
    goroutines that fill up the channel, and then be able to read from that
    channel. The answer should be 73, but I keep getting 18. Thanks for the
    help!
    --
    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/d/optout.
  • Shawn Milochik at Jul 9, 2014 at 2:34 pm
    Although others have already pointed out the problem, I wanted to link to
    this because it's a clear explanation and part of the official docs:

    https://code.google.com/p/go-wiki/wiki/CommonMistakes

    --
    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/d/optout.
  • Tyler Compton at Jul 9, 2014 at 7:08 pm
    Wow, looks like I stumbled over a really common mistake. I appreciate all the helpful material!

    --
    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/d/optout.

Related Discussions

Discussion Navigation
viewthread | post
Discussion Overview
groupgolang-nuts @
categoriesgo
postedJul 9, '14 at 7:18a
activeJul 10, '14 at 1:48a
posts8
users6
websitegolang.org

People

Translate

site design / logo © 2021 Grokbase