errgroup.withcontext 是唯一安全的初始化方式,因直接实例化会导致 mutex 未初始化而 panic;必须传入带取消能力的 ctx,且 gocontext() 用于 i/o 任务、go() 仅适用于极快 cpu 计算;wait() 仅返回首个错误且不捕获 panic,需手动 recover;errgroup 不限流、不汇总错误、不强制中断 goroutine,取消依赖业务代码主动检查 ctx.done()。

errgroup.WithContext 是唯一安全的初始化方式
直接 &errgroup.Group{} 或 new(errgroup.Group) 会导致上下文取消失效、任务卡死、资源泄漏。它内部 mutex 未初始化,调用 Go() 或 Wait() 可能 panic。
必须用 errgroup.WithContext(ctx),且传入的 ctx 需带取消能力(如 context.WithTimeout 或 context.WithCancel):
ctx, cancel := context.WithTimeout(context.Background(), 5*time.Second)-
defer cancel()—— 不加这句,超时后ctx不会主动关闭,errgroup无法响应 -
g, ctx := errgroup.WithContext(ctx)—— 返回的ctx是派生上下文,所有子任务共享同一取消信号
复用已取消的 ctx 创建新 errgroup 会触发 panic: context canceled,因为 WithCancel 内部检查了 ctx.Err() 状态。
Go() 和 GoContext() 必须按场景严格区分
Go() 只接受 func() error,完全不感知 ctx;GoContext() 显式接收 ctx 参数,并自动监听 ctx.Done()。混用会导致部分 goroutine “失联”——比如对 HTTP 请求用 Go() 却没手动检查 ctx.Err(),超时后仍阻塞在 http.Client.Do 上。
- I/O 类任务(HTTP、DB、RPC)一律用
GoContext(func(ctx context.Context) error { ... }),并优先使用支持 context 的 API(如req.WithContext(ctx)) - CPU 密集型纯计算(JSON 解析、base64 编码)可用
Go(),但需确保执行极快,否则应改用GoContext()并定期检查if ctx.Err() != nil { return ctx.Err() } - 不要在
GoContext()闭包里再调用context.WithTimeout—— 会覆盖上级ctx的取消链路
Wait() 返回 nil 不代表成功,错误可能被静默吞掉
g.Wait() 只返回第一个非 nil 错误,其余错误丢弃;它也不捕获 panic —— 若某个 Go() 闭包内 panic 且未 recover,整个程序崩溃,根本走不到 Wait()。
- 所有
Go()函数必须显式返回error,不能只log.Printf后return nil,否则错误被掩盖 - 易 panic 场景(如解析不可信 JSON、调用第三方 SDK)必须加
defer func() { if r := recover(); r != nil { ... } }(),把 panic 转为error返回 - 循环变量捕获错误常见:
for _, url := range urls { g.Go(func() error { return fetch(url) }) }中所有 goroutine 都会访问最后一个url,必须写成url := url提前捕获
errgroup 本身不控制并发数,也不汇总全部错误
它不是限流器,也不是错误收集器。默认行为是“任一出错即短路”,但已启动的任务继续运行;若要全部尽力执行并汇总错误,得自己维护 sync.Mutex + []error。
- 需要并发限制(如最多同时 10 个 HTTP 请求)时,必须配合
semaphore或带缓冲 channel,errgroup不提供该能力 - HTTP 场景下,若大量请求卡住,问题常出在
http.Transport连接池(如MaxIdleConns太小),而非errgroup本身 - 依赖错误类型做逻辑分支(如重试
context.DeadlineExceeded)时,注意g.Wait()返回的可能是更早发生的其他错误,无法保证是超时错误
真正容易被忽略的是:errgroup 不强制中断正在运行的 goroutine,取消靠的是任务自身配合 ctx.Done() 检查 —— 这个责任始终在业务代码里,不在 errgroup 库中。
golang免费学习笔记(深入):立即使用
在学习笔记中,你将探索golang的核心概念和高级技巧!











