Golang学习篇

您所在的位置:网站首页 ants的英语 Golang学习篇

Golang学习篇

2023-08-15 01:01| 来源: 网络整理| 查看: 265

目录

1. 为什么需要协程池?

2. 简单的协程池

3. go-playground/pool

4. ants(推荐)

1. 为什么需要协程池?

虽然go语言自带“高并发”的标签,其并发编程就是由groutine实现的,因其消耗资源低(大约2KB左右,线程通常2M左右),性能高效,开发成本低的特性而被广泛应用到各种场景,例如服务端开发中使用的HTTP服务,在golang net/http包中,每一个被监听到的tcp链接都是由一个groutine去完成处理其上下文的,由此使得其拥有极其优秀的并发量吞吐量。

但是,如果无休止的开辟Goroutine依然会出现高频率的调度Groutine,那么依然会浪费很多上下文切换的资源,导致做无用功。所以设计一个Goroutine池限制Goroutine的开辟个数在大型并发场景还是必要的。

2. 简单的协程池 package main import ( "fmt" "time" ) /* 有关Task任务相关定义及操作 */ //定义任务Task类型,每一个任务Task都可以抽象成一个函数 type Task struct { f func() error //一个无参的函数类型 } //通过NewTask来创建一个Task func NewTask(f func() error) *Task { t := Task{ f: f, } return &t } //执行Task任务的方法 func (t *Task) Execute() { t.f() //调用任务所绑定的函数 } /* 有关协程池的定义及操作 */ //定义池类型 type Pool struct { EntryChannel chan *Task //对外接收Task的入口 worker_num int //协程池最大worker数量,限定Goroutine的个数 JobsChannel chan *Task //协程池内部的任务就绪队列 } //创建一个协程池 func NewPool(cap int) *Pool { p := Pool{ EntryChannel: make(chan *Task), worker_num: cap, JobsChannel: make(chan *Task), } return &p } //协程池创建一个worker并且开始工作 func (p *Pool) worker(work_ID int) { //worker不断的从JobsChannel内部任务队列中拿任务 for task := range p.JobsChannel { //如果拿到任务,则执行task任务 task.Execute() fmt.Println("worker ID ", work_ID, " 执行完毕任务") } } //让协程池Pool开始工作 func (p *Pool) Run() { //1,首先根据协程池的worker数量限定,开启固定数量的Worker, // 每一个Worker用一个Goroutine承载 for i := 0; i < p.worker_num; i++ { fmt.Println("开启固定数量的Worker:", i) go p.worker(i) } //2, 从EntryChannel协程池入口取外界传递过来的任务 // 并且将任务送进JobsChannel中 for task := range p.EntryChannel { p.JobsChannel


【本文地址】


今日新闻


推荐新闻


CopyRight 2018-2019 办公设备维修网 版权所有 豫ICP备15022753号-3