深入剖析Go语言中的Select语句:并发控制的精髓

一、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 main

import (
    "fmt"
    "time"
)

func main() {
    //在某些场景下我们需要同时从多个通道接收数据,这个时候就可以用到golang中给我们提供的select多路复用

    //定义一个管道10个数据int
    intChan := make(chan int,10)
    for i :=0;i<10;i++ {
        intChan <- i
    }

   //2.定义一个管道 5个数据string
	stringChan := make(chan string, 5)
	for i := 0; i < 5; i++ {
		stringChan <- "hello" + fmt.Sprintf("%d", i)
	}
	//使用select来获取channel里面的数据的时候不需要关闭channel
	for {
		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 //注意退出...
		}
	}
}
  • 5
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值