errgroup 在 WaitGroup 的基础上实现子协程错误传递, 同时使用 context 控制协程的生命周期。

使用

errgroup 的使用非常简单

package main

import (
"context"
"fmt"
"time" "golang.org/x/sync/errgroup"
) func main() {
group, _ := errgroup.WithContext(context.Background())
for i := 0; i < 5; i++ {
index := i
group.Go(func() error {
fmt.Printf("start to execute the %d gorouting\n", index)
time.Sleep(time.Duration(index) * time.Second)
if index%2 == 0 {
return fmt.Errorf("something has failed on grouting:%d", index)
}
fmt.Printf("gorouting:%d end\n", index)
return nil
})
}
if err := group.Wait(); err != nil {
fmt.Println(err)
}
}

输出

输出结果如下:

start to execute the 0 gorouting

start to execute the 3 gorouting

start to execute the 2 gorouting

start to execute the 1 gorouting

start to execute the 4 gorouting

gorouting:1 end

gorouting:3 end

something has failed on grouting:0

代码分析

不管是否有协程执行失败, wait()都要等待所有协程执行完成

使用方法与 WaitGroup 类似。只是封装了 WaitGroup Add()Wait()方法。

  • 首先传递 context 初始化 errgroup 对象
  • 每一个 group.Go() 都会新启一个协程, Go()函数接受一个 func() error 函数类型
  • 使用 Wait()方法阻塞主协程,直到所有子协程执行完成

分析

errGroup 的结构如下:

type Group struct {
cancel func() //context cancel()
wg sync.WaitGroup
errOnce sync.Once //只会传递第一个出现错的协程的 error
err error //传递子协程错误
}

withContext

func WithContext(ctx context.Context) (*Group, context.Context) {
ctx, cancel := context.WithCancel(ctx)
return &Group{cancel: cancel}, ctx
}

Go

func (g *Group) Go(f func() error) {
g.wg.Add(1) go func() {
defer g.wg.Done()
if err := f(); err != nil {
g.errOnce.Do(func() {
g.err = err //记录子协程中的错误
if g.cancel != nil {
g.cancel()
}
})
}
}()
}

小结

  • errgroup 可以捕获和记录子协程的错误(只能记录最先出错的协程的错误)
  • errgroup 可以控制协程并发顺序。确保子协程执行完成后再执行主协程
  • errgroup 可以使用 context 实现协程撤销。或者超时撤销。子协程中使用 ctx.Done()来获取撤销信号

参考

errgroup godoc

errgroup 分析的更多相关文章

  1. drone的pipeline原理与代码分析

    最近的一个项目,需要实现一个工作任务流(task pipeline),基于之前CICD的经验,jenkins pipeline和drone的pipeline进入候选. drone是基于go的cicd解 ...

  2. 十二. Go并发编程--sync/errGroup

    一.序 这一篇算是并发编程的一个补充,起因是当前有个项目,大概の 需求是,根据kafka的分区(partition)数,创建同等数量的 消费者( goroutine)从不同的分区中消费者消费数据,但是 ...

  3. alias导致virtualenv异常的分析和解法

    title: alias导致virtualenv异常的分析和解法 toc: true comments: true date: 2016-06-27 23:40:56 tags: [OS X, ZSH ...

  4. 火焰图分析openresty性能瓶颈

    注:本文操作基于CentOS 系统 准备工作 用wget从https://sourceware.org/systemtap/ftp/releases/下载最新版的systemtap.tar.gz压缩包 ...

  5. 一起来玩echarts系列(一)------箱线图的分析与绘制

    一.箱线图 Box-plot 箱线图一般被用作显示数据分散情况.具体是计算一组数据的中位数.25%分位数.75%分位数.上边界.下边界,来将数据从大到小排列,直观展示数据整体的分布情况. 大部分正常数 ...

  6. 应用工具 .NET Portability Analyzer 分析迁移dotnet core

    大多数开发人员更喜欢一次性编写好业务逻辑代码,以后再重用这些代码.与构建不同的应用以面向多个平台相比,这种方法更加容易.如果您创建与 .NET Core 兼容的.NET 标准库,那么现在比以往任何时候 ...

  7. UWP中新加的数据绑定方式x:Bind分析总结

    UWP中新加的数据绑定方式x:Bind分析总结 0x00 UWP中的x:Bind 由之前有过WPF开发经验,所以在学习UWP的时候直接省略了XAML.数据绑定等几个看着十分眼熟的主题.学习过程中倒是也 ...

  8. 查看w3wp进程占用的内存及.NET内存泄露,死锁分析

    一 基础知识 在分析之前,先上一张图: 从上面可以看到,这个w3wp进程占用了376M内存,启动了54个线程. 在使用windbg查看之前,看到的进程含有 *32 字样,意思是在64位机器上已32位方 ...

  9. ZIP压缩算法详细分析及解压实例解释

    最近自己实现了一个ZIP压缩数据的解压程序,觉得有必要把ZIP压缩格式进行一下详细总结,数据压缩是一门通信原理和计算机科学都会涉及到的学科,在通信原理中,一般称为信源编码,在计算机科学里,一般称为数据 ...

随机推荐

  1. JVM(一) ---JVM的数据模型

    JVM的逻辑内存模型图 [逻辑内存模型图] ----- JVM内部分区 其实JVM内部不仅仅只有栈和堆 包括 程序计数器 . Java 虚拟机栈 .本地方法栈.Java 堆.方法区等 1. 程序计数器 ...

  2. BAT 电脑名 用户名

    @echo offecho 当前盘符:%~d0echo 当前登陆用户:%username%echo 当前盘符和路径:%~dp0echo 当前盘符和路径的短文件名格式:%~sdp0echo 当前批处理全 ...

  3. PPR管各种接头产品名称

    PPR管各种接头产品名称 http://ishare.iask.sina.com.cn/f/19n7gOsntbX.html

  4. 交互式报告系统 Dr. Tom | 华大基因培训资料

    华大科技服务开发一套优秀的交互式结题报告系统,适用于没有代码基础的老师分析自己的数据. http://report.bgi.com/ps/login/login.html 体验之后再做评价! 见云盘: ...

  5. Python 23种设计模式全(python例子)

    从今年5月份开始打算把设计模式都写到博客里,持续到现在总算是写完了.写的很慢,好歹算是有始有终.对这些设计模式有些理解的不准确,有些甚至可能是错的,请看到的同学拍砖留言.内容来源很杂,大部分参考或者摘 ...

  6. TextView: android:ellipsize="marquee" 跑马灯效果无效的问题

    今天练习的时候想实现一个文字的跑马灯效果,本来想自己手动实现的,不过突然想起来android里的TextView属性似乎自带了这个效果,叫: android:ellipsize ,平时都是把它的属性值 ...

  7. 005 DOM02

    在上一篇DOM的基础上,继续案例的实践. 一:案例 1.禁用文本框 <!DOCTYPE html> <html lang="en"> <head> ...

  8. restful swagger api java go

    rest框架使用swagger api,接口越来越多后性能会很差,如何优化? - 知乎https://www.zhihu.com/question/59349319 golang restful 框架 ...

  9. 0.9.0.RELEASE版本的spring cloud alibaba sentinel实例

    sentinel即哨兵,相比hystrix断路器而言,它的功能更丰富.hystrix仅支持熔断,当服务消费方调用提供方发现异常后,进入熔断:sentinel不仅支持异常熔断,也支持响应超时熔断,另外还 ...

  10. 零基础学Python-第一章 :Python介绍和安装-03.Python的安装

    官方版本的python下载以及安装方法,以及pycharm的安装和打开. 社区版就可以完全支持我们的需求了. 点击左侧的图片到右边. 在命令行输入python3 exit() 退出命令行的编辑器. p ...