go
runtime_error
ai_generated
true
恐慌:关闭已关闭的通道
panic: close of closed channel
ID: go/goroutine-channel-close-multiple
80%修复率
87%置信度
0证据数
2025-03-01首次发现
版本兼容性
| 版本 | 状态 | 引入 | 弃用 | 备注 |
|---|---|---|---|---|
| 1.21 | active | — | — | — |
| 1.22 | active | — | — | — |
根因分析
对已经关闭的通道再次调用close(),通常是由于多个协程试图关闭同一个通道。
English
Calling close() on a channel that has already been closed, typically due to multiple goroutines attempting to close the same channel.
解决方案
-
99% 成功率 Use sync.Once to ensure close is called only once
var closeOnce sync.Once closeOnce.Do(func() { close(ch) }) -
98% 成功率 Designate a single goroutine to close the channel
// Only one goroutine has access to close(ch) ch := make(chan int) go func() { // close when done close(ch) }()
无效尝试
常见但无效的做法:
-
Checking if channel is closed before closing
80% 失败
No built-in way to check if a channel is closed without risking a race condition.
-
Using recover() to catch panic
85% 失败
Recover does not prevent the panic from occurring; it only catches it after the fact.