package main
import("fmt""runtime""time")funcmain(){
ch :=make(chanint)// 用来进行数据通信的 channel
quit :=make(chanbool)// 用来判断是否退出的 channel//ch2 := make(chan string)gofunc(){// 写数据for i :=0; i <5; i++{
ch <- i
time.Sleep(time.Second)}close(ch)
quit <-true// 通知主go程 退出
runtime.Goexit()}()for{// 主go程 select 监听 chan数据流动select{case num :=<-ch:// 不可读,阻塞。可以读,将数据保存至num
fmt.Println("读到:", num)// 模拟使用数据case<-quit:// 不可读,阻塞。可以读,将主go程结束。//break // break 跳出 select 不可用//runtime.Goexit() // 终止 主 go 程 不可用return// 终止进程}
fmt.Println("============")// select 自身不带有循环机制,需借助外层 for 来循环监听}}
三、select的注意事项
①.监听的case中,没有满足监听条件,阻塞
②.监听的case中,有多个满足监听条件,任选一个执行
③.可以使用default来处理所有case都不满足监听条件的状况。 通常不用(会产生忙轮询)
④.select 自身不带有循环机制,需借助外层 for 来循环监听
⑤.break 跳出 select中的一个case选项 。类似于switch中的用法
四、select案例:斐波那契数列
package main
import("fmt""runtime")funcfibonacci(ch <-chanint, quit <-chanbool){for{select{case num :=<-ch:
fmt.Print(num," ")case<-quit://return
runtime.Goexit()//等效于 return}}}funcmain(){
ch :=make(chanint)
quit :=make(chanbool)gofibonacci(ch, quit)// 子go 程 打印fibonacci数列
x, y :=1,1for i :=0; i <40; i++{
ch <- x
x, y = y, x+y
}
quit <-true}