I am trying to use channels to communicate between two go routines. At first I created the channel of integers, then I passed it as parameter to a go routine which prints a sequence of numbers from 0 to 10. The outputs of those programs are not making sense.
This is the main code:
func Worker(identifier string, ch chan<- int) {
fmt.Printf("Entering worker %s\n", identifier)
for i := 0; i < 10; i++ {
fmt.Printf("Writing %d\n", i)
ch <- i
}
fmt.Printf("Exiting worker %s\n", identifier)
close(ch)
}
func main() {
ch := make(chan int)
go Worker("1", ch)
for v := range ch {
fmt.Printf("Reading %d\n", v)
}
}
For that code execution I got this output:
Entering worker 1
Writing 0
Writing 1
Reading 0
Reading 1
Writing 2
Writing 3
Reading 2
Reading 3
Writing 4
Writing 5
Reading 4
Reading 5
Writing 6
Writing 7
Reading 6
Reading 7
Writing 8
Writing 9
Reading 8
Reading 9
Exiting worker 1
Please, note that there are two writing executions then two reading executions.
Late on, I set a buffer size to make function like this:
func main() {
ch := make(chan int, 3) // <= Buffer
go Worker("1", ch)
for v := range ch {
fmt.Printf("Reading %d\n", v)
}
}
And then, got this output:
Entering worker 1
Writing 0
Writing 1
Writing 2
Writing 3
Writing 4
Reading 0
Reading 1
Reading 2
Reading 3
Reading 4
Writing 5
Writing 6
Writing 7
Writing 8
Writing 9
Reading 5
Reading 6
Reading 7
Reading 8
Reading 9
Exiting worker 1
Please, note that now we have 5 writing execution then 5 reading execution.
Once we have the code and outputs, there goes the final question: Why did those executions behave like this? In the first, wasn't it supposed to read and write only one number per time? Beyond that, why the second execution reads and write 5 numbers per time instead of 3 (since this is the buffer size)?
You're mixing up when the messages are printed and when the numbers are read from or written to the channel.
"Writing" messages don't happen when a write happens. They happen at some point between writes. Similarly, "Reading" messages happen at some point between reads.
Here's one way your first snippet could have gotten scheduled, that would have produced the displayed output:
Control keeps passing between main and Worker like this, each printing 2 messages before blocking.
Similarly, your second snippet could have been scheduled like this: