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)
}
- 在go routine中不断从c中读取十次数据,由于c一开始是空的,必然阻塞在读取操作;
- 调用fibonacci方法,quit条件不满足,只能在c中被放入了一个x的值并进行一次计算;
- 步骤1中阻塞的routine被唤醒(<-c操作条件满足),输出步骤2中的放入的值;
- routine循环,阻塞,fibonacci下一次循环将再次解除阻塞;
- 由于fibonacci和routine访问的是同一个c channel,不需要加锁来做同步就能避免routine同主程序间的竞争(比如routine没等主程序输出完就放入新的值进去等)
- routine循环结束后,quit放入了0值,由于c中的数据已经被输出完了,只能执行case <-quit,条件满足,退出。