go runtime_error ai_generated true

panic: close of closed channel

ID: go/goroutine-close-channel-twice

Also available as: JSON · Markdown · 中文
80%Fix Rate
87%Confidence
0Evidence
2024-04-05First Seen

Version Compatibility

VersionStatusIntroducedDeprecatedNotes
1.0 active
1.21 active

Root Cause

Calling close() on a channel that has already been closed, often due to multiple goroutines closing without coordination.

generic

中文

对已关闭的通道调用close(),通常由于多个协程未经协调地关闭。

Workarounds

  1. 95% success Use sync.Once to ensure close is called only once
    var once sync.Once
    once.Do(func() { close(ch) })
  2. 90% success Use a closed flag with mutex
    var mu sync.Mutex
    var closed bool
    mu.Lock()
    if !closed {
        close(ch)
        closed = true
    }
    mu.Unlock()

Dead Ends

Common approaches that don't work:

  1. Using recover() to catch panic and ignore 80% fail

    Recover hides the error but doesn't prevent data race or inconsistent state.

  2. Checking ch != nil before close 100% fail

    A closed channel is not nil; nil check doesn't prevent double close.