理解 Go 语言的分组操作

news/2024/9/23 6:35:38/

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

1. ErrGroup

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

1.1 ErrGroup 的基本用法

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

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

        1. WithContext

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

Go">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 方法的签名如下:

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 方法的签名如下:

Go">func (g *Group) TryGo(f func() error) bool

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

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

        4. Wait

        Wait 方法的签名如下:

Go">func (g *Group) Wait() error

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

        5. SetLimit

        SetLimit 方法的签名如下:

Go">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 才会返回第二个子任务的错误。

Go">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(

http://www.ppmy.cn/news/1509117.html

相关文章

c++精品小游戏(无错畅玩版)

一、俄罗斯方块 #include <stdio.h> #include <string.h> #include <stdlib.h> #include <time.h> #include <conio.h> #include <windows.h>#ifdef _MSC_VER // M$的编译器要给予特殊照顾 #if _MSC_VER < 1200 // VC6及以下版本 #err…

企业数据接口:失信被执行人(人员)查询

根据搜索关键字、名称等参数&#xff0c;获取失信被执行人相关信息 批量获取企业多维度信息

CCF-GESP8级考试—图论算法及综合应用(最小生成树)

&#x1f349;1 最小生成树的概念 1.1 连通图 &#x1f388; 连通图是图论中的一个重要概念&#xff0c;用于描述图中顶点之间是否存在路径相连。一个无向图中&#xff0c;如果从图中的任意一个顶点出发&#xff0c;都可以通过边的连接到达图中的任意其他顶点&#xff0c;则该…

网络安全流程规范文件解读(安全专业L1级)

技术能力项编号AQ-AQ-L1-02.01(安全维护作业计划执行能力) 课程目标&#xff1a; 通过学习课程&#xff0c;学员可以&#xff1a; 1.了解ZGYD网络安全流程规范 2.独立执行安全维护作业计划。 流程规范 一、《ZGYD远程接入安全管理办法》 二、《ZGYD网络运维账号口令管理办…

详解使用Goalng+Redis实现分布式锁

Redis实现分布式锁 前言 分布式锁的实现有三种方式 数据库乐观锁基于Redis的分布式锁基于Zookeeper的分布式锁分布式锁满足的条件 为了确保分布式锁可用,我们至少要保证锁的实现同时满足以下几个条件 互斥性:在任意时刻只有一个客户端能持有锁不会死锁:即使有一个客户端在…

Flutter实现水印打卡照片

公司要求拍照以后返回加一层水印在照片上&#xff0c;网上找了几个组件本来都实现了结果发现只有英文不给写中文气得要死 整体来说就是这个方法&#xff0c;思路就是把照片当做画布然后再画一个水印出来设置透明背景把两张图拼在一起 copyImageToDocumentDirectory方法是为了解…

WPF自定义控件的应用(DynamicResource的使用方法)

1 DynamicResource的使用方法 可以在字典文件 的抬头区写入数&#xff1a; <SolidColorBrush x:Key"PrimaryBackgroundColor" Color"#FFABAdB3"/><SolidColorBrush x:Key"TextBox.MouseOver.Border" Color"#FF7EB4EA"/>&l…

MySQL笔记-基础篇(一):查询

博客主页: 南来_北往 系列专栏&#xff1a;Spring Boot实战 MySQL是一种广泛使用的关系型数据库管理系统&#xff0c;它基于结构化查询语言&#xff08;SQL&#xff09;来管理和操作数据。下面将依次探讨MySQL查询的各个方面&#xff0c;确保理解扎实&#xff0c;能够在实…