go runtime_error ai_generated true

panic: sync: WaitGroup 在之前的 Wait 返回前被重用

panic: sync: WaitGroup is reused before previous Wait has returned

ID: go/waitgroup-misused-copy

其他格式: JSON · Markdown 中文 · English
80%修复率
90%置信度
0证据数
2024-05-21首次发现

版本兼容性

版本状态引入弃用备注
1.20 active
1.23 active

根因分析

在另一个 goroutine 仍处于 wg.Wait 时再次调用 wg.Add。通常发生在循环中跨迭代复用同一个 WaitGroup 而未重置。

English

wg.Add called again while another goroutine is still in wg.Wait. Typically happens with a loop that reuses the same WaitGroup across iterations without resetting.

generic

解决方案

  1. 95% 成功率
    for _, batch := range batches {
        var wg sync.WaitGroup
        for _, x := range batch {
            wg.Add(1)
            go func(x int) { defer wg.Done(); work(x) }(x)
        }
        wg.Wait()
    }
  2. 93% 成功率
    for _, batch := range batches {
        g := new(errgroup.Group)
        for _, x := range batch { x := x; g.Go(func() error { return work(x) }) }
        if err := g.Wait(); err != nil { return err }
    }

无效尝试

常见但无效的做法:

  1. 85% 失败

    Reassigning while Wait is in flight races on the struct; still panics or corrupts state.

  2. 80% 失败

    Sleep does not synchronize with Wait's completion; race remains.