首页>>后端>>Golang->worker pool(goroutine池)和 select 多路复用

worker pool(goroutine池)和 select 多路复用

时间:2023-11-30 本站 点击:0

Worker pool(goroutine池)

在工作中我们通常会使用可以指定启动的goroutine数量–worker pool模式,控制goroutine的数量,防止goroutine泄漏和暴涨。

funcmain(){jobs:=make(chanint,100)results:=make(chanint,100)//开启3个goroutineforid:=0;id<3;id++{goworker(id,jobs,results)}//生成5个jobfornum:=0;num<5;num++{jobs<-num}close(jobs)//输出结果fora:=0;a<5;a++{<-results}//死锁,只有close(results)可用//for{//x,ok:=<-results//if!ok{//break//}//fmt.Println(x)//}//死锁,只有close(results)可用//forx:=rangeresults{//fmt.Println(x)//}}funcworker(idint,jobs<-chanint,resultschan<-int){forj:=rangejobs{time.Sleep(time.Second)fmt.Printf("JobID:{%d}Jobis:%d\n",id,j)results<-j*2}}

输出结果如下:

JobID:{0}Jobis:0JobID:{2}Jobis:2JobID:{1}Jobis:1JobID:{2}Jobis:4JobID:{0}Jobis:3

Select多路复用

在某些场景下我们需要同时从多个通道接收数据。通道在接收数据时,如果没有数据可以接收将会发生阻塞。你也许会写出如下代码使用遍历的方式来实现:

for{//尝试从ch1接收值data,ok:=<-ch1//尝试从ch2接收值data,ok:=<-ch2…}

这种方式虽然可以实现从多个通道接收值的需求,但是运行性能会差很多。为了应对这种场景,Go内置了select关键字,可以同时响应多个通道的操作。

select的使用类似于switch语句,它有一系列case分支和一个默认的分支。每个case会对应一个通道的通信(接收或发送)过程。select会一直等待,直到某个case的通信操作完成时,就会执行case分支对应的语句。具体格式如下:

select{case<-ch1:...casedata:=<-ch2:...casech3<-data:...default:默认操作}

举个小例子来演示下select的使用:

funcmain(){ch:=make(chanint,1)fori:=0;i<10;i++{select{casex:=<-ch:fmt.Println(x)casech<-i:fmt.Printf("%d放进去了\n",i)}}}

使用select语句能提高代码的可读性。

可处理一个或多个channel的发送/接收操作。

如果多个case同时满足,select会随机选择一个。

对于没有caseselect{}会一直等待,可用于阻塞main函数。


本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。
如若转载,请注明出处:/Golang/4603.html