06|并发等待:如何降低实时系统的响应延时?
徐逸

你好,我是徐逸。
在上节课中,我们学习了如何借助资源复用来降低 Golang 运行时的资源损耗,从而提升单机吞吐。在资源复用的技巧里,我们重点强调了协程池这一关键技巧。
有了协程并发的运用,自然少不了并发相关的技术。所以在今天的课程里,我们就来聊一聊协程并发等待技术——WaitGroup 类型和 errgroup 包。只有熟练地掌握这些并发技术,我们才能够在面对各种并发场景时,更快、更好地解决各种并发问题。
首先,我们来想一个问题:倘若我们需要向多个下游发起并发请求,并且必须得等待所有请求返回时,你会用 Golang 的哪个并发类型来实现呢?

图1 并发调用
WaitGroup 类型
当面对这种场景时,常规解决方法是用 Golang 的基础并发类型 WaitGroup。WaitGroup 的作用是阻塞等待多个并发任务执行完成。WaitGroup 类型主要包含下面几个方法。
第一个是 Add 方法,在任务运行之前,需要调用 Add 方法,用于设置需要等待完成的任务数,Add 方法传进去的数值之和,需要和任务数相等。
第二个是 Done 方法,每个任务完成时,需要调用 Done 方法,用于告知 WaitGroup 对象已经有一个任务运行完成。
第三个是 Wait 方法,当需要等待所有并发任务完成时,调用 Wait 方法,用于阻塞主协程。
公开
同步至部落
取消
完成
0/2000
笔记
复制
AI
- 深入了解
- 翻译
- 解释
- 总结

1. WaitGroup类型是Golang的基础并发类型,用于阻塞等待多个并发任务执行完成,包含Add、Done和Wait方法。 2. errgroup包是Golang提供的并发扩展库,对WaitGroup进行了封装,在并发等待的基础功能上提供了错误处理和任务取消功能。 3. Group类型的Go方法用于传入具有错误返回值的函数类型,Wait方法会阻塞等待所有传入Go方法的函数全部运行完毕,并且在任务完成后能够对错误进行处理。 4. 任务取消功能通过WithContext函数创建Group对象,传入Go方法的函数需要实现select-done模式,利用context来停止所有相关任务。 5. errgroup包还可以限制同时并发运行的最大协程数,通过SetLimit方法设置可同时运行的最大协程数,达到最大协程数时会阻塞创建新协程运行任务。
仅可试看部分内容,如需阅读全部内容,请付费购买文章所属专栏
《Go 服务开发高手课》,新⼈⾸单¥59
《Go 服务开发高手课》,新⼈⾸单¥59
立即购买
© 版权归极客邦科技所有,未经许可不得传播售卖。 页面已增加防盗追踪,如有侵权极客邦将依法追究其法律责任。
登录 后留言
全部留言(2)
- 最新
- 精选
- 橙func TestCancel(t *testing.T) { results := make([]string, len(urls)) // 用WithContext函数创建Group对象 eg, ctx := errgroup.WithContext(context.Background()) for index, url := range urls { url := url index := index // 调用Go方法 eg.Go(func() error { select { case <-ctx.Done(): // select-done模式取消运行 return errors.New("task is cancelled") default: // Fetch the URL. resp, err := http.Get(url) if err != nil { return err // 返回错误 } defer resp.Body.Close() body, err := io.ReadAll(resp.Body) if err != nil { return err // 返回错误 } results[index] = string(body) return nil } }) } // Wait for all HTTP fetches to complete. // 等待所有任务执行完成,并对错误进行处理 if err := eg.Wait(); err != nil { fmt.Println("Failured fetched all URLs.") } } 这个方法感觉直接用可以cancle的context会不会比较好,如果检测到错误直接cancel掉。现在感觉这个例子虽然支持cancel,虽然在讲cancel,但是例子没有支持cancel,看起来怪怪的。2024-12-20归属地:北京
- lJ可以基于 WaitGroup 和一个错误通道(error channel,容量不小于控制的协程并发数,避免阻塞)来收集并发协程中的错误信息,任务协程发生的错误写入err channel中,开启一个协程读取err channel。也可以初始化一个全局的错误切片errs,在协程出错时将err赋值给errs。 开源实现有 1、github.com/facebookgo/errgroup,扩展了标准库的sync.WaitGroup,errors收集协程执行时发生的错误 type Group struct { wg sync.WaitGroup mu sync.Mutex errors MultiError } 2、github.com/vardius/gollback,gollback.All方法返回所有的错误 本质上都是通过err切片保存任务协程中的错误信息2024-12-20归属地:江苏
收起评论