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

理解 Go 语言的分组操作

        共享资源保护、任务编排和消息传递是 Go 并发编程中常见的场景,而分组执行一批相同的或类似的任务则是任务编排中的一类情形。下面我们专门介绍分组编排的一些常用场景和同步原语,主要用来处理一组任务。我们先来介绍一个非常常用的同步原语,即 ErrGroup。

1. ErrGroup

        ErrGroup 是 Go 官方提供的一个同步扩展库。我们经常会遇到需要将一个通用的父任务拆分成几个小任务并发执行的场景,其实,这样做可以有效地提高程序的并发度.

1.1 ErrGroup 的基本用法

        golang.org/x/sync/errgroup 包下定义了一个 Group struct, 它就是我们要介绍的 ErrGroup 同步原语,其底层是基于 WaitGroup 实现的。

        在使用 ErrGroup 时,我们要用到 5  个方法,分别是 WithContext、Go、TryGo、Wait 和 SetLimit。

        1. WithContext

        在创建一个 Group 对象时,需要使用 WithContext 方法:

func WithContext(ctx context.Context) (*Group,context.Context)

        该方法传入一个 Context, 返回一个 Group 以及一个派生的 Context。

        这个派生的 Context 会在下面两种情况下被取消:

  • 传给 Go 方法的函数 f 第一次返回非空 (nil) 的 error。
  • Wait 方法第一次返回

        Group 的零值也是合法的。也就是不通过 WithContext 生成 Group, 而是使用它的零值。这是可以的,只不过这样就没有可以监控是否可以撤销的 Context 了。

        另外需要注意的是,如果传递给 WithContext 的 ctx 参数是一个可撤销的 Context, 那么它被撤销时并不会中止正在执行的子任务。

        2. Go

        Go 方法的签名如下:

func (g *Group) Go(f func() error)

        该方法在新的 goroutine 中调用函数 f,该函数可以返回 error。

        如果当前 Group 中活跃的 goroutine 的数量超过了设置的数量限制,那么它会被阻塞,直到有可用的新的 goroutine 加入。

        如果调用函数 f 第一次返回非空的 error ,则会撤销这个 Group 的 Context, 这给调用者留下了想象的空间。如果这个 Group 是使用 WithContext 创建的,那么 Wait 方法会返回这个 error。

        Go 方法被并发调用时,函数 f  可以是不一样的,只要是符合其签名的函数,就都可以被当作参数,并没有规定同一个 Group 必须使用相同的函数。

        3. TryGo

        TryGo 方法的签名如下:

func (g *Group) TryGo(f func() error) bool

        TryGo 方法尝试创建新的 Group 来执行函数 f, 不过要求当前活跃的 goroutine 的数量不能超过限制,否则直接返回,不会被阻塞。

        返回的结果指示函数 f 是否被执行,其中 true 表示成功启动 goroutine 来执行函数 f ,false 表示函数 f 没有被执行。 

        4. Wait

        Wait 方法的签名如下:

func (g *Group) Wait() error

        Wait 方法等待所有的 goroutine 都执行完成才返回,否则一直被阻塞。如果函数 f 执行时返回了非空的 error,那么 Wait 方法将会把第一个非空的 error 返回。 

        5. SetLimit

        SetLimit 方法的签名如下:

func (g *Group) SetLimit(n int)

        该方法限制同时最多有 n 个活跃的 goroutine 执行函数 f 。n 为负值代表 goroutine 的数量没有限制。

        设置完毕后,后续活跃的 goroutine 的数量不能超过这个限制。如果有活跃的 goroutine,则不能进行限制。

        ErrGroup 由 WaitGroup、信号量(用channel实现)、Once、Context 组合而成。信号量用于控制活跃的  goroutine 的数量, WaitGroup 用于等待所有的任务执行完成,Once 用于控制设置 error, Context 用于控制撤销以及 error 的发生。

1.2 ErrGroup 使用示例

        1. 返回第一个错误

        我们先来看一个简单的例子。在这个例子中启动了三个任务,其中第二个子任务执行失败,其他两个子任务执行成功。只有在这三个子任务都执行完成后,group.Wait 才会返回第二个子任务的错误。

package mainimport ("errors""fmt""time""golang.org/x/sync/errgroup"
)func main(){var g errgroup.Group// 启动第一个子任务,它执行成功g.Go(func() error{time.Sleep(5 *time.Second)fmt.Println("exec #1")return nil})// 启动第二个子任务,它执行失败g.Go(

相关文章:

  • 北京网站建设多少钱?
  • 辽宁网页制作哪家好_网站建设
  • 高端品牌网站建设_汉中网站制作
  • JAVA中的ArrayDeque和LinkedList实现Deque,前者不能存NULL结点,后者可以存放NULL。
  • 【upload]-ini-[SUCTF 2019]CheckIn-笔记
  • MySQL 中主键索引的页分裂:深入探讨
  • STM32家族系列的区别
  • 使用go实现一个简单的聊天服务器
  • 机器学习/深度学习——梯度下降法(Gradient descent)详解. 步骤清晰 0基础可看
  • 月薪5W的项目经理是如何面试的?这份面试攻略请收好!
  • Jetson Orin NX 功耗模式选择:MAXN与25W模式的对比与优化建议
  • 聊一聊 Netty 数据搬运工 ByteBuf 体系的设计与实现
  • IP地址证如何实现HTTPS访问?(内网IP、公网IP)
  • Python 之Scikit-learn(五) -- Scikit-learn提供的数据集及其详细介绍
  • 用户案例|Maple 软件在德国亚琛工业大学化学教学中的创新应用
  • PHPStorm 环境配置与应用详解
  • Axios 详解与使用指南
  • 子网掩码是什么以及子网掩码相关计算
  • 【css3】浏览器内核及其兼容性
  • Centos6.8 使用rpm安装mysql5.7
  • Fastjson的基本使用方法大全
  • input实现文字超出省略号功能
  • JavaScript 是如何工作的:WebRTC 和对等网络的机制!
  • jquery cookie
  • puppeteer stop redirect 的正确姿势及 net::ERR_FAILED 的解决
  • python学习笔记 - ThreadLocal
  • vue脚手架vue-cli
  • 简单数学运算程序(不定期更新)
  • 力扣(LeetCode)357
  • 聊一聊前端的监控
  • 猫头鹰的深夜翻译:Java 2D Graphics, 简单的仿射变换
  • 如何在 Tornado 中实现 Middleware
  • 06-01 点餐小程序前台界面搭建
  • Salesforce和SAP Netweaver里数据库表的元数据设计
  • 关于Android全面屏虚拟导航栏的适配总结
  • ​ 轻量应用服务器:亚马逊云科技打造全球领先的云计算解决方案
  • #我与Java虚拟机的故事#连载13:有这本书就够了
  • (1)Android开发优化---------UI优化
  • (C语言)编写程序将一个4×4的数组进行顺时针旋转90度后输出。
  • (delphi11最新学习资料) Object Pascal 学习笔记---第14章泛型第2节(泛型类的类构造函数)
  • (NSDate) 时间 (time )比较
  • (保姆级教程)Mysql中索引、触发器、存储过程、存储函数的概念、作用,以及如何使用索引、存储过程,代码操作演示
  • (官网安装) 基于CentOS 7安装MangoDB和MangoDB Shell
  • (十二)python网络爬虫(理论+实战)——实战:使用BeautfulSoup解析baidu热搜新闻数据
  • (十六)串口UART
  • (转)eclipse内存溢出设置 -Xms212m -Xmx804m -XX:PermSize=250M -XX:MaxPermSize=356m
  • (转载)虚幻引擎3--【UnrealScript教程】章节一:20.location和rotation
  • *_zh_CN.properties 国际化资源文件 struts 防乱码等
  • .equals()到底是什么意思?
  • .NET COER+CONSUL微服务项目在CENTOS环境下的部署实践
  • .NET 应用架构指导 V2 学习笔记(一) 软件架构的关键原则
  • .NET/C# 使窗口永不激活(No Activate 永不获得焦点)
  • .net解析传过来的xml_DOM4J解析XML文件
  • .net连接MySQL的方法
  • /bin/bash^M: bad interpreter: No such file or directory
  • @Autowired多个相同类型bean装配问题
  • @ComponentScan比较
  • [ Linux 长征路第二篇] 基本指令head,tail,date,cal,find,grep,zip,tar,bc,unname