当前位置: 首页 > news >正文

go语言实现协程池

代码:

package mainimport ("sync"
)// GoPool 协程池结构
type GoPool struct {taskChannel   chan func()   // 任务存放的队列taskMutex     sync.Mutex    // 用于保证计数正确性的锁maxWorkerNum  int64         // 协程最大数curWorkerNum  int64         // 当前协程数waitGroup     sync.WaitGroup // 用于等待所有任务完成
}// NewGoPoolWithCapacity 创建指定协程数量和最大任务容量的协程池
func NewGoPoolWithCapacity(workerNum int64, maxTask int) *GoPool {if workerNum < 1 || maxTask < 1 {panic("invalid go pool param")}return &GoPool{taskChannel:  make(chan func(), maxTask),maxWorkerNum: workerNum,curWorkerNum: 0,}
}// NewGoPool 创建指定协程数量的协程池,默认最大任务容量为 1024
func NewGoPool(workerNum int64) *GoPool {return NewGoPoolWithCapacity(workerNum, 1024)
}// Go 提交一个任务到协程池
func (p *GoPool) Go(newTask func()) {if newTask == nil {return}p.taskMutex.Lock()// 对原有任务添加释放 wait group 功能p.waitGroup.Add(1)innerTask := func() {defer p.waitGroup.Done()newTask()}if p.curWorkerNum < p.maxWorkerNum {// 如果当前协程数量小于最大协程数量,则新建 goroutinep.curWorkerNum++go func() {defer func() {p.taskMutex.Lock()p.curWorkerNum--p.taskMutex.Unlock()}()innerTask() // 执行当前任务// 执行完当前任务之后,去队列拉一下最新任务for channelTask := range p.taskChannel {channelTask()}}()} else {// 如果当前协程数量大于等于最大协程数量,则当前任务需要排队p.taskChannel <- innerTask}p.taskMutex.Unlock()
}// CloseAndWait 关闭协程池,并等待所有任务执行完成
func (p *GoPool) CloseAndWait() {close(p.taskChannel)p.waitGroup.Wait()
}// CloseWithoutWait 关闭协程池,但是不等待所有任务执行完成
func (p *GoPool) CloseWithoutWait() {close(p.taskChannel)
}

使用:

func main() {// 创建一个最大 5 个 worker 的协程池pool := NewGoPool(5)// 提交 10 个任务for i := 0; i < 10; i++ {taskID := ipool.Go(func() {// 模拟任务执行// fmt.Printf("Task %d is running\n", taskID)// time.Sleep(time.Second)// fmt.Printf("Task %d is done\n", taskID)})}// 关闭协程池并等待所有任务完成pool.CloseAndWait()
}
http://www.dtcms.com/a/309754.html

相关文章:

  • leetcode 118. 杨辉三角 简单
  • django操作orm整套
  • android MVC/MVP/MVVM/MVI架构发展历程和编写范式
  • 如何在Android中创建自定义键盘布局
  • MySQL时间处理完全指南:从存储到查询优化
  • Apache RocketMQ中 Consumer Group(消费者组)的详细说明
  • 2025新征程杯全国54校园足球锦标赛在北京世园公园隆重开幕
  • 使用Nginx部署前端项目
  • 深度学习:反向传播算法(Backpropagation)
  • 力扣:2477. 到达首都的最少油耗
  • 从资源闲置到弹性高吞吐,JuiceFS 如何构建 70GB/s 吞吐的缓存池?
  • 11. 五种 IO 模型与阻塞 IO
  • 操作系统-lecture4(进程的调度)
  • GaussDB 数据库设计规范
  • Windows CMD命令大全
  • 乐观锁是数据库和多线程编程中常用的一种控制并发的方法
  • 性能测试-性能测试中的经典面试题一
  • 深度解读 CSGHub:开源协议、核心功能与产品定位
  • 网络编程接口bind学习
  • HTTPS的工作原理
  • 微信小程序服务器配置指南:从入门到高可用架构的腾讯云方案
  • CS231n-2017 Lecture8深度学习框架笔记
  • linux编译基础知识-编译时路径和运行时路径
  • 基于python实现的高效文件压缩工具:Zstandard、LZ4、Brotli 一站式解决方案
  • wsl配置文件(wsl: 检测到 localhost 代理配置,但未镜像到 WSL。NAT 模式下的 WSL 不支 持 localhost 代理。)
  • 世代距离(GD)和反转世代距离(IGD)详析
  • Python入门Day14:面向对象编程初步(OOP入门)
  • 国内短剧CPS系统开发:技术架构与商业化实践
  • 离线智能破局,架构创新突围:RockAI与中国AI的“另一条车道”
  • MySQL CPU占用过高排查指南