Golang: Why does increasing the size of a buffered channel eliminate output from my goroutines?

Issue

I am trying to understand why making the buffer size of a channel larger changes causes my code to run unexpectedly. If the buffer is smaller than my input (100 ints), the output is as expected, i.e., 7 goroutines each read a subset of the input and send output on another channel which prints it. If the buffer is the same size or larger than the input, I get no output and no error. Am I closing a channel at the wrong time? Do I have the wrong expectation about how buffers work? Or, something else?

package main

import (
    "fmt"
    "sync"
)

var wg1, wg2 sync.WaitGroup

func main() {
    share := make(chan int, 10)
    out := make(chan string)
    go printChan(out)
    for j:= 1; j<=7; j++ {
        go readInt(share, out, j)
    }
    for i:=1; i<=100; i++ {
        share <- i
    }
    close(share)
    wg1.Wait()
    close(out)
    wg2.Wait()
}
func readInt(in chan int, out chan string, id int) {
    wg1.Add(1)
    for n := range in {
        out <- fmt.Sprintf("goroutine:%d was sent %d", id, n)
    }
    wg1.Done()
}
func printChan(out chan string){
    wg2.Add(1)
    for l := range out {
        fmt.Println(l)
    }
    wg2.Done()
}

To run this:
Small buffer, expected output. http://play.golang.org/p/4r7rTGypPO
Big buffer, no output. http://play.golang.org/p/S-BDsw7Ctu

Solution

This has nothing directly to do with the size of the buffer. Adding the buffer is exposing a bug in where you’re calling waitGroup.Add(1)

You have to add to the WaitGroup before you dispatch the goroutine, otherwise you may end up calling Wait() before the waitGroup.Add(1) executes.

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

The reason it works in the first and not the second, is because the synchronous sends ensure that the gouroutines have executed at least that far. In the second example, the for loop fills up the channel, closes it and calls Wait before anything else can happen.

Answered By – JimB

Answer Checked By – Robin (GoLangFix Admin)

Leave a Reply

Your email address will not be published.