go
runtime_error
ai_generated
true
panic: 重复关闭 channel
panic: close of closed channel
ID: go/close-of-closed-channel
80%修复率
90%置信度
0证据数
2024-01-19首次发现
版本兼容性
| 版本 | 状态 | 引入 | 弃用 | 备注 |
|---|---|---|---|---|
| 1.0+ | active | — | — | — |
根因分析
两个 goroutine 都调用了 close(ch),或函数被重试导致 defer close 执行了两次。Go 在第二次 close 时 panic。
English
Two goroutines both called close(ch), or a deferred close ran twice because the function was retried. Go panics on the second close.
解决方案
-
97% 成功率
var closeOnce sync.Once closeOnce.Do(func() { close(ch) }) -
95% 成功率
// Only the producer closes func produce(ch chan<- int, n int) { defer close(ch) for i := 0; i < n; i++ { ch <- i } }
无效尝试
常见但无效的做法:
-
80% 失败
The flag itself is racy without a mutex; two goroutines can both read false and both call close.
-
60% 失败
If the main goroutine is not the sole owner or the function can run concurrently, this does not guarantee single close.