select:多路复用机制,用于监听多个管道,当我们不知道该怎么去处理channel的关闭时,可使用select
注意:select里的case执行是无序的
用法
select { //不停的在这里检测case <-chanl : //检测有没有数据可以读//如果chanl成功读取到数据,则进行该case处理语句,处理完退出selectcase chan2 <- 1 : //检测有没有可以写//如果成功向chan2写入数据,则进行该case处理语句,处理完退出select//假如没有default,那么在以上两个条件都不成立的情况下,就会在此阻塞//一般default会不写在里面,select中的default子句总是可运行的,因为会很消耗CPU资源default://如果以上都没有符合条件,那么则进行default处理流程,处理完退出select}
实例
func main() {intchan :=make(chan int,10)primechan :=make(chan int,10)for i:=0;i<10;i++{intchan <- iprimechan <- i*2}label:for {select {case a:=<-intchan:fmt.Println("intchan----",a)case b:=<-primechan:fmt.Println("primechan---",b)default:break label}}}
斐波那契数列
//ch只写,quit只读func fbn(ch chan<- int, quit <-chan bool) {x, y := 1, 1for {//监听channel数据的流动select {case ch <- x: //往里写 。第一次写的时候是1,如果没有地方读的话,那么这里会阻塞x, y = y, x+y //第一次是往ch写1,y的值也是1,下一次y的值就是x+ycase <-quit:return}}}func main() {ch := make(chan int) //数字通道quit := make(chan bool) //程序是否结束go func() {for i := 0; i < 8; i++ {num := <-ch //这里读是因为防止select那里会阻塞fmt.Println(num)}quit <- true}()fbn(ch, quit)}
timeout 机制
func main() {ch := make (chan int)select {case <-ch:case <-time.After(time.Second * 1): //一般不会用time.Afterfmt.Println("超时啦!")}}
判断channel是否阻塞
func main() {ch := make (chan int,1) // 注意这里给的容量是1ch <- 1select {case ch <- 2:default:fmt.Println("通道channel已经满啦,塞不下东西了!")}}
