GO:Channel and Select
The select
statement lets a goroutine wait on multiple communication operations.
A select
blocks until one of its cases can run, then it executes that case. It chooses one at random if multiple are ready.
package main
import "fmt"
func fibonacci(c, quit chan int) {
x, y := 0, 1
for {
select {
case c <- x:
x, y = y, x+y
case <-quit:
fmt.Println("quit")
return
}
}
}
func main() {
c := make(chan int)
quit := make(chan int)
go func() {
for i := 0; i < 10; i++ {
fmt.Println(<-c)
}
quit <- 0
}()
fibonacci(c, quit)
}
First time I read the code, I wonder why the first case in select block only runs 10 times, not infinitely.
The reason is, the channel c, which initialized by make(chan int)
, is an unbuffered channel. That's to say, unless it was fetched, the sending operation will be blocked. So case c <- x
can only be jumped into when fmt.Println(<-c)
was executed. More details, c <- x
is executed but not finished, at this time, c
has a value x
. In the other goroutine, when coming to <-c
, it will succeed fetching the value x
. Immediately after this, c <- x
is finished and makes c
still an unbuffered channel, not buffered channel with capacity 1.