Here is an example of book go in action https://github.com/goinaction/code/blob/master/chapter2/sample/search/search.go
// Launch a goroutine to monitor when all the work is done.
go func() {
// Wait for everything to be processed.
waitGroup.Wait()
// Close the channel to signal to the Display
// function that we can exit the program.
close(results)
}()
// Start displaying results as they are available and
// return after the final result is displayed.
Display(results)
If I move waitGroup.Wait() and close(results) out of the goroutine function, program is blocked because the results in channel are not read yet, and it blocks at writing other more result into channel after it gets to a "size". But if I use a big size buffered channel:
results := make(chan *Result, 100)
program recovers back to normal. It seems that channel is blocked due to size limit and can not write more before consuming it. Is there a size limit for unbeffered channel ? why it writes a few messages into channel and decreases WaitGroup counter a little, then blocks itself at there ?
An unbuffered channel by definition doesn't have a buffer size. Sending blocks if there is something to read. Please take the go tour to familiarize yourself.
The reason the code above blocks is that you are waiting for the WaitGroup counter to reach zero. I assume this is done after the goroutines (the ones you don't show) are done writing to the channel. One of them writes, but all others are blocking. Display
is supposed to read from the channel (you also don't show that code), but never gets called. This means that nothing is ever consuming from the channel.
Changing to a size 100 channel is only a temporary workaround. If you send more than 100 elements to the channel, it will still block as nothing is reading from it.
Buffer size means is a number of elements you can send to it without blocking it. By default, it's 0 (unbuffered channel), so if you sending something to channel its blocking till the moment channel will be read by goroutine. When you making a size of 100 for channel, the channel will be blocked at the 100th message.
Capacity (number of elements what can be stored in a channel) for unbuffered channel is zero. So it gets blocked right now when one goroutine starts to write to it. And unlocks when another goroutine would read that message from it.
When you make it buffered - that means all your messages (at least in this case 100 is enough) are put into the buffer. And no need to wait until some another goroutine will read them from channel
Why you can pass several messages in this case? That means other process is reading them.