Here is a code example taken from "Google I/O 2012 - Go Concurrency Patterns" (slides)
package main
import (
"fmt"
"time"
)
func main() {
joe := boring("Joe")
ann := boring("Ann")
for i := 0; i < 5; i++ {
fmt.Println(<-joe)
fmt.Println(<-ann)
}
fmt.Println("The end")
}
func boring(msg string) <-chan string {
c := make(chan string)
go func() {
for i := 0; ; i++ {
c <- fmt.Sprintf("%s %d", msg, i)
time.Sleep(time.Second)
}
}()
return c
}
The output:
Joe 0
Ann 0
Joe 1
Ann 1
Joe 2
Ann 2
Joe 3
Ann 3
Joe 4
Ann 4
The end
This is the explanation by Rob Pike, the speaker (16:33 in the video): "...we're reading a value from Joe and a value from Ann. And because of the synchronization nature of the channels, the two guys are taking turns, not only in printing the values out, but also in executing them. Because if Ann is ready to send a value but Joe hasn't done that yet, Ann will still be blocked, waiting to deliver the value to main."
This confused me. What's the meaning of "if Ann is ready to send a value but Joe hasn't done that yet, Ann will still be blocked"? As we know, a channel builds the communication between two goroutines and synchronizes their executions. But we have crated two channels here (joe
and ann
). The main goroutine talks with two new goroutines via joe
and ann
, respectively. Does that mean the synchronization nature is also valid between channels? Or that the main goroutine can talk with only one other goroutine at a time?
It just means those channels are unbuffered.
fmt.Println(<-joe)
fmt.Println(<-ann)
The second line won't be able to execute before the first completes.
And the first won't complete until something writes in joe's channel.
Ann won't be able to write in Ann's channel if that channel has already a value.
And that channel won't be read (fmt.Println(<-ann)
) until joe's channel is read first (fmt.Println(<-joe)
).
Both channels are independent (unaware of each other), but the sequential nature of the read operations make one waiting for the other to be read first.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With