go runtime_error ai_generated true

panic: WaitGroup 在上次 Wait 返回前被重用

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

ID: go/waitgroup-added-after-wait

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

版本兼容性

版本状态引入弃用备注
1.0+ active

根因分析

在一个 goroutine 阻塞于 wg.Wait() 期间,另一个 goroutine 调用了 wg.Add(),或 WaitGroup 在未同步的情况下跨批次重用。

English

wg.Add() was called from a goroutine while another goroutine was blocked in wg.Wait(), or the WaitGroup was reused across batches without synchronization.

generic

解决方案

  1. 97% 成功率
    var wg sync.WaitGroup
    for _, item := range items {
        wg.Add(1)
        go func(it Item) {
            defer wg.Done()
            process(it)
        }(item)
    }
    wg.Wait()
  2. 93% 成功率
    for _, batch := range batches {
        var wg sync.WaitGroup
        for _, x := range batch {
            wg.Add(1)
            go func(v X) { defer wg.Done(); work(v) }(x)
        }
        wg.Wait()
    }

无效尝试

常见但无效的做法:

  1. 75% 失败

    The ordering of Add vs Wait is the actual constraint; moving Wait just changes where the race manifests and can cause premature return.

  2. 80% 失败

    No happens-before guarantee; under load the Add still races with Wait.