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.
writeToChan
is able to write 3 values?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<br>
main read 1 -: 42<br>
main read 2 -: 9<br>
Playground link: https://play.golang.org/p/DYzfYh-kXnC
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. The writeToChan
routine waits for a second before writing the first value to the channel
The goroutine rdFrmChan
is also blocked, because it is waiting to read on the channel ch
After 1s, when the sleep on writeToChan
expires, the first write (c <- 42
) will unblock your main routine first, causing the value to be stored in x
i.e. 42
Next the rdFrmChan
is unblocked on the next write to the channel (c <- 27
) and sees the value 27. The routine terminates at this point after printing the value
At 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 <-ch
and print it