go runtime_error ai_generated true

panic:sync:WaitGroup 在上一次 Wait 返回前被复用

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

ID: go/waitgroup-wait-race

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

版本兼容性

版本状态引入弃用备注
1.18 active — — —
1.22 active — — —

根因分析

在上一轮 Wait() 尚未返回时就再次调用了 Add() 复用 WaitGroup,sync 包明确禁止这种用法。

English

A WaitGroup was reused (Add called) while a previous Wait() had not yet returned, which is explicitly disallowed by the sync package.

generic

解决方案

  1. 95% 成功率
    for _, batch := range batches {
        var wg sync.WaitGroup
        for _, it := range batch {
            wg.Add(1)
            go func(it Item) { defer wg.Done(); process(it) }(it)
        }
        wg.Wait()
    }
  2. 92% 成功率
    for _, stage := range stages {
        g := new(errgroup.Group)
        for _, t := range stage { g.Go(t.Run) }
        if err := g.Wait(); err != nil { return err }
    }

无效尝试

常见但无效的做法:

  1. 85% 失败

    Recover leaves the WaitGroup in an inconsistent state and the concurrent Wait may return early or hang.

  2. 80% 失败

    Two Waits on the same group do not resolve the reuse race; it can still panic.

  3. 90% 失败

    Timing-based, non-deterministic, and fails under load.