go runtime_error ai_generated true

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

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

Also available as: JSON · Markdown · 中文
80%Fix Rate
86%Confidence
0Evidence
2024-11-01First Seen

Version Compatibility

VersionStatusIntroducedDeprecatedNotes
1.0 active
1.22 active

Root Cause

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

generic

中文

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

Workarounds

  1. 85% success 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% success 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)

Dead Ends

Common approaches that don't work:

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

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

  2. Checking channel length before send 95% fail

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