用go语言实现一个有界协程池

写在文章开头

本篇文章算是对go语言系列的一个收尾,通过go语言实现一个实现一个简单的有界协程池。

在这里插入图片描述

Hi,我是 sharkChili ,是个不断在硬核技术上作死的 java coder ,是 CSDN的博客专家 ,也是开源项目 Java Guide 的维护者之一,熟悉 Java 也会一点 Go ,偶尔也会在 C源码 边缘徘徊。写过很多有意思的技术博客,也还在研究并输出技术的路上,希望我的文章对你有帮助,非常欢迎你关注我的公众号: 写代码的SharkChili

因为近期收到很多读者的私信,所以也专门创建了一个交流群,感兴趣的读者可以通过上方的公众号获取笔者的联系方式完成好友添加,点击备注 “加群” 即可和笔者和笔者的朋友们进行深入交流。

在这里插入图片描述

详解go语言协程池的实现

整体交互流程设计

我们希望创建一个协程池,该协程池大小由用户决定,主协程不断生产任务并投递到channel中,协程池收到任务后,如果发现没有对应处理的协程worker则创建一个协程并处理传入的任务,反之这些任务就会有序得等待协程有序调度执行:

在这里插入图片描述

定义worker

基于上图我们给出worker的接口定义,按照我们的实现每一个任务都是一个worker,协程池的协程可以从channel中得到对应的Worker 并执行其Task方法:

type Worker interface {Task()
}

声明协程池

基于worker我们封装一个worker池,也就是本文提到的协程池,可以看到该Pool有一个worker的通道用于存放主协程投递进来的任务,而wg则用于控制协程的生命周期,这一点我们会在后续的工作代码中详尽说明:

type Pool struct {//记录主协程投递的任务work chan Worker//控制工作协程的生命周期wg   sync.WaitGroup
}

创建协程池

有了协程池的定义之后,我们就可以编写协程池的,可以看到我们可以通过入参决定channel和协程的大小,通过传入maxGoroutines 设置wg的大小,当协程都没有任务执行时,才会调用wgDone方法,确保所有任务执行完成后,主协程才能退出:

func New(maxGoroutines int) *Pool {//创建指定协程数的channelp := Pool{work: make(chan Worker, maxGoroutines),}//基于协程数创建倒计时门闩p.wg.Add(maxGoroutines)//创建maxGoroutines个协程获取channel的任务执行for i := 0; i < maxGoroutines; i++ {go func() {for w := range p.work {w.DoTask()}//任务执行完成且channel关闭之后,按下倒计时门闩p.wg.Done()}()}//返回pool的指针return &p
}

投递任务

当我们需要投递任务时,就可以将自实现的worker投递到channle中:

func (p *Pool) Run(w Worker) {//将任务w投递到channel中p.work <- w
}

关闭协程池

最后我们给出关于协程池关闭的实现,其逻辑比较简单:

  1. 关闭channel不再接受新任务。
  2. 调用waitGroupWait方法等待所有协程执行完再返回。
func (p *Pool) ShutDown() {close(p.work)p.wg.Wait()
}

测试代码

最后我们给出本文的测试代码,使用示例比较简单:

  1. 定义一个姓名切片,作为测试数据。
  2. 创建一个名为namePrinter 的结构体,内部包含name属性,该结构体会继承Worker实现打印姓名的Task方法。
  3. 创建一个channel和协程大小都为2的Pool
  4. 通过多协程循环遍历name切片并将其封装成namePrinter投递到chanel中。
  5. 协程池的协程消费这些打印姓名的任务。
  6. 调用shutDown方法等待协程池内部协程工作完成后退出主协程。
// 创建一个测试用的姓名切片
var names = []string{"user.go-1","user.go-2","user.go-3","user.go-4","user.go-5",
}// 实现worker接口 打印姓名
type namePrinter struct {name string
}func (n *namePrinter) Task() {fmt.Println(n.name)time.Sleep(time.Second)
}func main() {//创建还有两个协程的poolp := work.New(2)//创建main协程的倒计时门闩var wg sync.WaitGroupwg.Add(100 * len(names))//多协程投递任务到poolfor i := 0; i < 100; i++ {for _, name := range names {np := namePrinter{name: name,}go func() {p.Run(&np)wg.Done()}()}}//等待任务投递完成wg.Wait()fmt.Println("执行结束,关闭pool")p.ShutDown()}

小结

自此,本文基于go语言的并发技术实现了一个简单的协程池,希望对你有所帮助。而go语言系列也到此告一段落。

我是 sharkchiliCSDN Java 领域博客专家开源项目—JavaGuide contributor,我想写一些有意思的东西,希望对你有帮助,如果你想实时收到我写的硬核的文章也欢迎你关注我的公众号: 写代码的SharkChili
因为近期收到很多读者的私信,所以也专门创建了一个交流群,感兴趣的读者可以通过上方的公众号获取笔者的联系方式完成好友添加,点击备注 “加群” 即可和笔者和笔者的朋友们进行深入交流。

在这里插入图片描述

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

HDR视频相关标准-HDR vivid(二)

上文介绍了HDRvivid的一些技术。今天从全局角度来看看HDR视频的处理流程&#xff0c;HDR视频系统&#xff0c;即建立一个比SDR视频更大的色彩/亮度坐标体系&#xff0c;并改变系统的传输函数&#xff0c;以再现更大的色域(WCG)和更高的亮度动态范围。 菁彩 HDR技术的专业术语 …

【ROSUbuntu】常用工具合集

1. 源 ADM64 ubuntu | 镜像站使用帮助 | 清华大学开源软件镜像站 | Tsinghua Open Source Mirror arm64 ubuntu-ports | 镜像站使用帮助 | 清华大学开源软件镜像站 | Tsinghua Open Source Mirror 2. FileZilla sudo apt-get install filezilla 3. Nomachine8 AMD64

操作系统实战(四)(linux+C语言)

目录 实验目的 前提知识 实验题目 题目分析 实验程序 头文件 头文件实现 核心代码文件 &#xff08;各类进程&#xff09; 生产者 抽烟者A 抽烟者B 抽烟者C makefile文件 实验运行 运行结果分析 总结 实验目的 加深对并发协作进程同步与互斥概念的理解&…

Jenkins配置(插件/角色/凭证)

目录 传送门前言一、Jenkins插件管理1、更换为国内下载源2、中文汉化插件下载&#xff08;不推荐&#xff09;3、低版本Jenkins爆红插件安装4、低版本Jenkins插件持续报错解决办法 二、Jenkins用户角色三、Jenkins凭证管理&#xff08;svn/git&#xff09;1、Username with pas…

NIO流(多路复用技术)

目录 什么是NIO使用场景 NIO(new IO)相关包路径NIO的实现基础NIO的核心组件Buffer缓冲区详解数据如何从磁盘读到用户进程 ChannelChannel的使用 其他组件字符集和Charset文件锁NIO工具类使用Files的FileVisitor遍历文件和目录使用WatchService监控文件变化访问文件属性 什么是N…

什么样的无线麦克风好?一文看懂哪种麦克风降噪效果好

作为视频创作者&#xff0c;拍摄视频除了要注意拍摄的画质外&#xff0c;声音的录制也很重要。声音录制的清晰度也会直接影响整个作品的整体水平&#xff0c;要想录的声音清晰&#xff0c;有专业级录制效果&#xff0c;必须选好麦克风&#xff0c;而无线领夹麦克风&#xff0c;…

【工具分享】Annabelle勒索病毒解密工具

前言 Annabelle勒索病毒灵感来自恐怖电影系列 Annabelle。除了文件加密功能外&#xff0c;Annabelle 勒索软件还会试图禁用防火墙&#xff0c;强制停止一系列正在运行程序&#xff0c;通过连接的 USB 驱动器进行传播。 特征 勒索内容&#xff1a; Annabelle 使用 AES256 CBC 加…

【Linux】线程同步和生产者-消费者模型

目录 一. 线程同步1. 条件变量2. 条件变量接口条件变量的创建及初始化条件变量的销毁条件变量等待条件变量唤醒 3. 条件变量同步解决抢占问题 二. 生产者-消费者模型1. 什么是生产者-消费者模型2. 为什么要使用生产者-消费者模型3. 生产者-消费者模型特点4. 基于阻塞队列实现生…

技术前沿:三品PLM系统引领工程变更管理新趋势

引言 在当今快速变化的制造行业&#xff0c;产品生命周期管理&#xff08;PLM&#xff09;系统已成为企业不可或缺的工具之一。PLM系统不仅帮助企业优化产品开发流程&#xff0c;还对工程变更管理&#xff08;ECM&#xff09;起着至关重要的作用。本文将探讨PLM系统在工程变更…

解决ssh报错,.ssh/id_rsa: No such file or directory Permission denied (publickey)

拉取依赖或者代码时说没有权限 首先我们可以看到的是这个报错但是我们的远程确实配置ssh密钥 首先我们可以看到的是这个报错 但是我们的远程确实配置ssh密钥 我们可以在我们项目路径下添加一下我们的私钥如&#xff1a; 首先确定我们ssh是正常启动的eval $(ssh-agent)我们可以…

AC/DC电源模块:提供高质量的电力转换解决方案

BOSHIDA AC/DC电源模块&#xff1a;提供高质量的电力转换解决方案 AC/DC电源模块是一种电力转换器件&#xff0c;可以将交流电转换为直流电。它通常用于各种电子设备和系统中&#xff0c;提供高质量的电力转换解决方案。 AC/DC电源模块具有许多优点。首先&#xff0c;它能够提…

让大模型变得更聪明:人工智能的未来发展之路

&#x1f49d;&#x1f49d;&#x1f49d;欢迎来到我的博客&#xff0c;很高兴能够在这里和您见面&#xff01;希望您在这里可以感受到一份轻松愉快的氛围&#xff0c;不仅可以获得有趣的内容和知识&#xff0c;也可以畅所欲言、分享您的想法和见解。 推荐:kwan 的首页,持续学…

以JVM新特性看Java的进化之路:从Loom到Amber的技术篇章

引言&#xff1a; JVM的最新特性通过在效率、功能和易用性方面的创新&#xff0c;对Java的未来发展产生了深远的影响。以下是几个关键特性如何塑造了Java的未来&#xff1a; 正文&#xff1a; 轻量级并发 - 项目Loom&#xff1a; 项目Loom通过引入虚拟线程&#xff08;也被称为…

江苏职称申报大揭秘:你所不知道的那些细节

大家好&#xff01;今天我将带大家深入探索江苏职称申报的一些你可能从未关注过的细节。对于在江苏工作的工程类小伙伴们来说&#xff0c;这些信息或许能助你一臂之力&#xff0c;让你在职称申报的道路上更加顺畅。 我们要明确的是&#xff0c;江苏省的工程类职称申报主要有三种…

每日一题——只需一行Python秒杀:PAT乙级1009 说反话!但不能故步自封!(举一反三+思想解读+逐步优化)

一个认为一切根源都是“自己不够强”的INTJ 个人主页&#xff1a;用哲学编程-CSDN博客专栏&#xff1a;每日一题——举一反三Python编程学习Python内置函数 Python-3.12.0文档解读 目录 我的写法 各部分功能分析&#xff1a; 综合时间复杂度 综合空间复杂度 总结 思路…

读人工智能时代与人类未来笔记15_改变人类经验

1. 认识世界的方式 1.1. 信仰 1.2. 理性 1.2.1. 理性不仅革新了科学&#xff0c;也改变了我们的社会生活、艺术和信仰 1.2.2. 在其浸染之下&#xff0c;封建等级制度瓦解了&#xff0c;而民主&#xff0c;即理性的人应该自治的理念崛起了 1.3. 人工智能 1.3.1. 这种转变将…

大数据开发面试题【Kafka篇】

83、介绍下Kafka&#xff0c;Kafka的作用?Kafka的组件?适用场景? kafka是一个高吞吐量、可扩展的分布式消息传递系统&#xff0c;在处理实时流式数据&#xff0c;并能够保证持久性和容错性 可用于数据管道、流分析和数据继承和关键任务应用&#xff08;发布/订阅模式&#…

Vue3+Ant design 实现Select下拉框一键全选/清空

最近在做后台管理系统项目的时候&#xff0c;产品增加了一个让人非常苦恼的需求&#xff0c;让在Select选择器中添加一键全选和清空的功能&#xff0c;刚开始听到的时候真是很懵&#xff0c;他又不让在外部增加按钮&#xff0c;其实如果说在外部增加按钮实现全选或者清空的话&a…

3、python安装-linux系统下

安装前置依赖软件&#xff0c;安装完成后&#xff0c;打开官网&#xff0c;下载linux系统下的python安装包&#xff1a; 选择最新的版本 点击最新版本&#xff0c;进入版本对应的界面&#xff0c; 选择第一个进行源码的编译&#xff0c;右键选择复制连接地址&#xff0c; 回到终…

HTML+CSS+JS(web前端大作业)~致敬鸟山明简略版

HTMLCSSJS【动漫网站】网页设计期末课程大作业 web前端开发技术 web课程设计 文章目录 一、网站题目 二、网站描述 三、网站介绍 四、网站效果 五、 网站代码 文章目录 一、 网站题目 动漫网站-鸟山明-龙珠超 二、 网站描述 页面分为页头、菜单导航栏&#xff08;最好可下拉&…