一、select多路复用
1、select说明
- 传统的方法在遍历管道时,如果不关闭会阻塞而导致deadlock,在实际开发中,可能我们不好确定什么关闭该管道
- 这种方式虽然可以实现从多个管道接收值的需求,但是运行性能会差很多
- 为了应对这种场景,Go内置了select关键字,可以同时响应多个管道的操作
- select的使用类似于switch语句,它有一系列case分支和一个默认的分支
- 每个case会对应一个管道的通信(接收或发送)过程
- select会一直等待,直到某个case的通信操作完成时,就会执行case分支对应的语句
- 具体格式如下:
select {case <- chan1://如果chan1成功读到数据,则进行该case处理语句case chan2 <- 1 ://如果成功向chan2写入数据,则进行该case处理语句default ://如果上面都没有成功,则进入default处理流程}
2、select的使用
- 使用select语句能提高代码的可读性
- 可处理一个或多个channel的发送/接收操作
- 如果多个caes同时满足,select会随机选择一个
- 对于没有case的select{}会一直等待,可用于阻塞main函数
package mainimport ("fmt""time"
)func main() {//在某些场景下我们需要同时从多个通道接收数据,这个时候就可以用到golang中给我们提供的select多路复用//定义一个管道10个数据intintChan := make(chan int,10)for i :=0;i<10;i++ {intChan <- i}//2.定义一个管道 5个数据stringstringChan := make(chan string, 5)for i := 0; i < 5; i++ {stringChan <- "hello" + fmt.Sprintf("%d", i)}//使用select来获取channel里面的数据的时候不需要关闭channelfor {select {case v := <-intChan:fmt.Printf("从 intChan 读取的数据%d\n", v)time.Sleep(time.Millisecond * 50)case v := <-stringChan:fmt.Printf("从 stringChan 读取的数据%v\n", v)time.Sleep(time.Millisecond * 50)default:fmt.Printf("数据获取完毕")return //注意退出...}}
}