go runtime_error ai_generated true

panic: 向已关闭的 channel 发送数据

panic: send on closed channel

ID: go/send-on-closed-channel

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

版本兼容性

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

根因分析

生产者 goroutine 在另一个 goroutine 关闭 channel 后仍发送数据。通常是 defer 中的 close 与仍在运行的兄弟生产者竞争。

English

A producer goroutine sends to a channel after another goroutine has closed it. Usually a close in a defer while sibling producers are still running.

generic

解决方案

  1. 97% 成功率
    var wg sync.WaitGroup
    for i := 0; i < n; i++ {
        wg.Add(1)
        go func(id int) {
            defer wg.Done()
            for v := range src(id) { out <- v }
        }(i)
    }
    go func() { wg.Wait(); close(out) }()
  2. 92% 成功率
    select {
    case out <- v:
    case <-done:
        return
    }

无效尝试

常见但无效的做法:

  1. 85% 失败

    The check-then-send is not atomic; a close can land between the check and the send.

  2. 70% 失败

    Recover silences the crash but the message is silently dropped; downstream logic may hang waiting for it.