找回密码
 会员注册
查看: 16|回复: 0

Golang协程池的使用

[复制链接]

4

主题

0

回帖

13

积分

新手上路

积分
13
发表于 2024-10-11 20:37:05 | 显示全部楼层 |阅读模式
点击上方蓝字关注我们!背景系统开发部分需求涉及到了多任务执行,而多任务执行过程中需要处理并发问题,都知道Golang本身是支持高并发的,其实很多语言都支持并发,像Java也可以创建多个线程(Thread),但是为什么要强调Golang支持高并发呢?那是因为Golang并发执行100w个协程。(coroutine)也不会觉得特别吃力,但是Java并发执行1w个线程(Thread)其性能下降就显而易见了,因此支持高并发也是Golang的特性之一。Golang的并发是通过协程来实现支持的,Go中main函数入口本身是一个主协程,如果我们没有创建子协程,那么这种程序执行模式就是串行(即一件事情做完再做另外一件事)可想而知这种模式效率低下,所以多用户量的网站使用这种网络请求模式不可取。并行的话(同一时间多个任务同时执行),这种模式不太现实,因为没有那么多核的CPU。那就只剩下并发模式了(同一时间段内多个任务交替间隔执行),Golang每个协程执行的都是一个函数。Golang使用协程处理并发任务效率比较高,但是我们在实际的开发过程中真的给每个任务都新开一个子协程吗?启动子协程越多占用的系统资源越多,那么程序的执行效率反而会受到影响,因此需要使用协程池来限制协程的启动数量。实现方案协程池的实现是有入口队列entryChannel和任务队列jobChannel以及具体做任务的协程worker组成,画图如下:协程池代码如下:packagemainimport("fmt""time")//golang协程池使用/*有关Task任务相关定义及操作*///定义任务Task类型,每一个任务Task都可以抽象成一个函数typeTaskstruct{fufunc()error//一个无参的函数类型}//通过NewTask来创建一个TaskfuncNewTask(ffunc()error)*Task{t:=Task{fu:f,}return&t}//执行Task任务的方法func(t*Task)Execute(){_=t.fu()//调用任务所绑定的函数}/*有关协程池的定义及操作*///定义池类型typePoolstruct{//对外接收Task的入口EntryChannelchan*Task//协程池最大worker数量,限定Goroutine的个数worker_numint//协程池内部的任务就绪队列JobsChannelchan*Task}//创建一个协程池funcNewPool(capint)*Pool{p:=Pool{EntryChannel:make(chan*Task),worker_num:cap,JobsChannel:make(chan*Task),}return&p}//协程池创建一个worker并且开始工作func(p*Pool)worker(work_IDint){//worker不断的从JobsChannel内部任务队列中拿任务fortask:=rangep.JobsChannel{//如果拿到任务,则执行task任务task.Execute()fmt.Println("workerID",work_ID,"执行完毕任务")}}//让协程池Pool开始工作func(p*Pool)Run(){//1,首先根据协程池的worker数量限定,开启固定数量的Worker,//每一个Worker用一个Goroutine承载fori:=0;i
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 会员注册

本版积分规则

QQ|手机版|心飞设计-版权所有:微度网络信息技术服务中心 ( 鲁ICP备17032091号-12 )|网站地图

GMT+8, 2024-12-26 12:34 , Processed in 0.333480 second(s), 26 queries .

Powered by Discuz! X3.5

© 2001-2024 Discuz! Team.

快速回复 返回顶部 返回列表