Go 并发控制 errgroup.Group的实现示例

 更新时间:2026年04月15日 08:30:51   作者:Go_error  
本文主要介绍了Go 并发控制 errgroup.Group的实现示例,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧

errgroup (golang.org/x/sync/errgroup) 为一组协程 goroutines 在执行共同任务的子任务时,提供同步、错误传播和上下文取消的功能。

对于要等待 n 个线程完成后再进行下一步的同步操作的做法,常见使用 sync.WaitGroup 来等待一组事件。

errgroup.Group 与 sync.WaitGroup 类似,但它增加了对返回错误任务的处理能力,以及限制协程并发数的能力

使用方法与 WaitGroup 类似,只是封装了 WaitGroup 的 Add() 和 Wait() 方法,解决 WaitGroup 无法返回错误的问题。

package main
import (
 "fmt"
 "time"
 "golang.org/x/sync/errgroup"
)
func main() {
 g := &errgroup.Group{}
 for i := 0; i < 5; i++ {
  index := i
  g.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 := g.Wait(); err != nil {
  fmt.Println(err)
 }
}
// Output:
// start to execute the 4 gorouting
// start to execute the 1 gorouting
// start to execute the 0 gorouting
// start to execute the 2 gorouting
// start to execute the 3 gorouting
// gorouting:1 end
// gorouting:3 end
// something has failed on grouting:0

如果多个 goroutine 出现错误,errgroup 只会获取到第一个出错的 goroutine 的错误信息。不管是否有协程执行失败,wait() 都要等待所有协程执行完成。

支持 context :

g, _ := errgroup.WithContext(context.Background()) // 支持 context

Wait() 方法可多次调用,依然可以得到 group 的 error 信息:

 ...
 if err := g.Wait(); err != nil {
  fmt.Println(err)
 }
 if err := g.Wait(); err != nil { // 可再次调用 Wait,依然可以得到 group 的 error 信息
  fmt.Println(err)
 }

限制最大并发数:

SetLimit() 方法用于限制该组中最多同时运行的 goroutine 数量,参数代表的是当前同时处于活动状态(处理业务)的 goroutine 的最多数量。

package main
import (
 "log"
 "time"
 "golang.org/x/sync/errgroup"
)
func main() {
 jobs := make(chan int, 10)
 go func() {
  for i := 0; i < 8; i++ {
   jobs <- i + 1
  }
  close(jobs)
 }()
 eg:= &errgroup.Group{}
 eg.SetLimit(3)
 for j := range jobs {
  j := j
  eg.Go(func() error {
   log.Printf("handle job: %d\n", j)
   time.Sleep(2 * time.Second)
   return nil
  })
 }
 eg.Wait()
}

上面的示例创建了一组 goroutines 来处理 job,同一时间允许最多 3 个 goroutine 处于活动状态。

Output:

2024/12/17 18:28:19 handle job: 3
2024/12/17 18:28:19 handle job: 1
2024/12/17 18:28:19 handle job: 2
2024/12/17 18:28:21 handle job: 4
2024/12/17 18:28:21 handle job: 6
2024/12/17 18:28:21 handle job: 5
2024/12/17 18:28:23 handle job: 7
2024/12/17 18:28:23 handle job: 8

从示例运行结果中的时间戳我们可以看到:虽然我们创建了很多 goroutine,但同一时间内处理活动状态(正在处理 job)的 goroutine 的数量最多为 3 个。

其内部实现就是将带缓冲 channel 用作计数信号量 (counting semaphore) 来限制最大并发数。

到此这篇关于Go 并发控制 errgroup.Group的实现示例的文章就介绍到这了,更多相关Go errgroup.Group内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!

相关文章

  • 为什么Go语言把类型声明放在后面?

    为什么Go语言把类型声明放在后面?

    今天小编就为大家分享一篇关于为什么Go语言把类型声明放在后面?,小编觉得内容挺不错的,现在分享给大家,具有很好的参考价值,需要的朋友一起跟随小编来看看吧
    2019-04-04
  • Go语言中hot path的作用

    Go语言中hot path的作用

    热路径指的是经常执行的性能敏感的代码路径,优化这些路径可以显著提高应用性能,通过工具如pprof进行性能分析,识别和优化热路径,能有效提升系统的响应能力和可靠性
    2024-10-10
  • golang方法中receiver为指针与不为指针的区别详析

    golang方法中receiver为指针与不为指针的区别详析

    这篇文章主要给大家介绍了关于golang方法中receiver为指针与不为指针区别的相关资料,其实最大的区别应该是指针传递的是对像的引用,文中通过示例代码介绍的非常详细,需要的朋友可以参考借鉴,下面来一起看看吧。
    2017-10-10
  • 使用Go语言实现接口继承的方式

    使用Go语言实现接口继承的方式

    在Go语言中,接口(interface)是一种定义方法集合的类型,它并不包含方法的具体实现,只是规定实现该接口的类型必须提供这些方法的实现,下面我将通过示例代码来详细解释如何使用Go语言实现接口组合,以及为什么这种方式可以看作是实现接口继承的一种方式
    2024-05-05
  • Golang获取当前时间代码

    Golang获取当前时间代码

    本文给大家汇总介绍了golang中的相关的时间的操作,有需要的小伙伴可以拿走参考下
    2018-10-10
  • Golang垃圾回收器执行链路详细分析

    Golang垃圾回收器执行链路详细分析

    垃圾回收简称GC,就是对程序中不再使用的内存资源进行自动回收释放的操作,这篇文章主要介绍了Golang垃圾回收器执行链路详细分析的相关资料,文中通过代码介绍的非常详细,需要的朋友可以参考下
    2025-12-12
  • Go实现超时控制的具体使用

    Go实现超时控制的具体使用

    本文主要介绍了Go中TimeoutControlWrapper实现超时控制,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2025-08-08
  • 浅谈golang fasthttp踩坑经验

    浅谈golang fasthttp踩坑经验

    本文主要介绍了golang fasthttp踩坑经验,文中通过示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2021-11-11
  • 深入理解Go语言中defer和panic的执行顺序

    深入理解Go语言中defer和panic的执行顺序

    defer 和 panic 的执行顺序是一个重要的概念,本文主要介绍了Go语言中defer和panic的执行顺序,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2025-05-05
  • go-cache的基本使用场景示例解析

    go-cache的基本使用场景示例解析

    这篇文章主要为大家介绍了go-cache的基本使用场景示例解析,有需要的朋友可以借鉴参考下,希望能够有所帮助,祝大家多多进步,早日升职加薪
    2023-04-04

最新评论