This seems to challenge my understanding of unbuffered channel, which is that it can only take one value and then it would block for a reader to read it.
- How in the following code
writeToChanis able to write 3 values? - More so surprisingly, how are those values available to be read later albeit not in same order?
An excerpt from https://golang.org/doc/effective_go#channels
Receivers always block until there is data to receive. If the channel is unbuffered, the sender blocks until the receiver has received the value. If the channel has a buffer, the sender blocks only until the value has been copied to the buffer; if the buffer is full, this means waiting until some receiver has retrieved a value.
package main
import (
"fmt"
"time"
)
func main() {
ch := make(chan int)
go writeToChan(ch)
go rdFrmChan(ch)
x := <- ch
fmt.Println("main read 1 -:",x)
fmt.Println("main read 2 -:",<-ch)
}
func writeToChan(c chan int) {
time.Sleep(time.Second * 1)
c <- 42
c <- 27
c <- 9
}
func rdFrmChan(c chan int) {
fmt.Println("Go routine read :", <-c)
}
Output:
Go routine read : 27
main read 1 -: 42
main read 2 -: 9
Playground link: https://play.golang.org/p/DYzfYh-kXnC
CodePudding user response:
Each line of the excerpt pasted is proven by your example code, if you understand the sequence of events happening.
After the goroutines are started, your main routine is blocked reading from the channel
c, as it is yet to see a value to read. ThewriteToChanroutine waits for a second before writing the first value to the channelThe goroutine
rdFrmChanis also blocked, because it is waiting to read on the channelchAfter 1s, when the sleep on
writeToChanexpires, the first write (c <- 42) will unblock your main routine first, causing the value to be stored inxi.e. 42Next the
rdFrmChanis unblocked on the next write to the channel (c <- 27) and sees the value 27. The routine terminates at this point after printing the valueAt this point, there is only value to be written and one to be read. The third write (
c <- 9) from the goroutine allows the main routine to read the value as part of<-chand print it
