go runtime_error ai_generated true

恐慌:向已关闭的通道发送数据(发送者在关闭后发送)

panic: send on closed channel (from sender after close)

ID: go/goroutine-close-channel-from-sender

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

版本兼容性

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

根因分析

发送者协程在另一个协程关闭通道后发送数据,通常由于竞态条件。

English

Sender goroutine sends to a channel after another goroutine has closed it, often due to race.

generic

解决方案

  1. 85% 成功率 Use a done channel to signal senders to stop
    done := make(chan struct{})
    ch := make(chan int)
    go func() {
        for {
            select {
            case <-done:
                return
            case ch <- 1:
            }
        }
    }()
    close(ch) // but close done first
    close(done)
  2. 90% 成功率 Use sync.WaitGroup to ensure all sends complete before close
    var wg sync.WaitGroup
    for i := 0; i < 5; i++ {
        wg.Add(1)
        go func() {
            defer wg.Done()
            ch <- 1
        }()
    }
    wg.Wait()
    close(ch)

无效尝试

常见但无效的做法:

  1. Using recover() to catch panic and log 90% 失败

    Recover doesn't fix the race; data may be lost.

  2. Checking channel length before send 95% 失败

    len(ch) doesn't indicate closed state; send still panics.