直接起 goroutine 很容易写出“看起来并发,实际上不可控”的代码。只要其中一个任务失败,其他任务是否继续、错误如何返回、ctx 是否取消,都需要明确。

errgroup.WithContext 的价值在于把错误和取消绑定起来。一个任务返回错误后,派生 ctx 会取消,其他任务可以尽快退出。

g, ctx := errgroup.WithContext(ctx)
for _, id := range ids {
    id := id
    g.Go(func() error {
        return syncOne(ctx, id)
    })
}
if err := g.Wait(); err != nil {
    return err
}

如果任务数量可能很大,要加并发限制。Go 新版本的 errgroup 支持 SetLimit,比手写信号量更清楚。

我的判断标准是:只要 goroutine 的生命周期超过当前函数,就必须能说清楚谁取消它、谁等待它、错误去哪了。

分类: Go 语言笔记 标签: Go 并发 errgroup

评论

-- 评论已关闭 --

全部评论