golang_select: select的用法介绍

Go语言的select关键字用于监听多个通道,类似于switch-case但每个case必须包含IO操作。当所有通道都被阻塞时,若存在default语句,则执行default并继续后续代码;若无default,select会被阻塞直至某个通道可用。通常不推荐使用default以避免忙轮询。select可用于监听数据通道和退出开关,实现超时退出功能,以及通过空的select{}使main函数保持运行。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

select

作用:

可以监听多个通道(同switch-case语句基本一样)

select的一大限制: 每一个case语句中必须是一个IO操作

select {
    case <- chan1:
    	//如果chan1成功读取到该数据,就进行该case处理语句
    case chan2 <- 1:
    	//如果chan2成功写入数据,就进行该case处理语句
    default:
    	//如果上面都没有成功,则进入default处理流程
}

如果没有任意一个条语句可以执行(即所有的通道都被阻塞),会出现两种情况:

  1. 如果有default语句,那么就执行default语句,同时程序的执行会从select语句后的语句中恢复.
  2. 没有default语句,那么select语句将被阻塞,直到至少有一个通信可以进行下去.

注意: 一般不使用default语句,如果其它case不满足条件会阻塞,最后会执行到default(不会阻塞),程序会不停地轮询

场景:如果监听到数据通道有值就打印,如果监听到退出开关有值就退出

func main() {
	c:=make(chan int)		//数据通道
	quit:=make(chan bool)	//退出开关
	//子go程写数据
	go func() {
		for i:=1;i<=5 ;i++  {
			c<-i			//将i写入通道
			time.Sleep(time.Second)
		}
		quit<-true			//退出开关
	}()
	//主go程读数据
	for  {
		select{			//用来监听通道
			case num:=<-c:
				fmt.Println("读取到",num)
			case <-quit:
				return ;
		}
		time.Sleep(time.Second)
	}
}
  1. select只是监听通道,不会阻塞(case可以产生阻塞)
  2. 在select中不用设置default,防止忙轮训在select中不用设置default,防止忙轮询

select实现超时退出

场景:有时候会出现go程阻塞的情况,可以利用select来设置超时,避免整个程序进入阻塞

func main() {
	c:=make(chan int)
	quit:=make(chan bool)
	go func() {
		for  {
			select{
				case num:=<-c:
					fmt.Println(num)
				case <-time.After(time.Second*2):
					fmt.Println("超时退出")
					quit<-true
			}
		}
	}()
	<-quit
}

空的select可以阻塞 main 函数

func main() {
	go func() {
		for{
			fmt.Println("Golang")
		}
	}()
	select {	//阻塞
	}
}

此处的select{}会阻塞main函数,让其不退出,一直在后台执行​(相当于for{}死循环)。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值