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,条件满足,退出。
有疑问加站长微信联系(非本文作者)