go
runtime_error
ai_generated
true
恐慌:关闭已关闭的通道
panic: close of closed channel
ID: go/goroutine-close-channel-twice
80%修复率
87%置信度
0证据数
2024-04-05首次发现
版本兼容性
| 版本 | 状态 | 引入 | 弃用 | 备注 |
|---|---|---|---|---|
| 1.0 | active | — | — | — |
| 1.21 | active | — | — | — |
根因分析
对已关闭的通道调用close(),通常由于多个协程未经协调地关闭。
English
Calling close() on a channel that has already been closed, often due to multiple goroutines closing without coordination.
解决方案
-
95% 成功率 Use sync.Once to ensure close is called only once
var once sync.Once once.Do(func() { close(ch) }) -
90% 成功率 Use a closed flag with mutex
var mu sync.Mutex var closed bool mu.Lock() if !closed { close(ch) closed = true } mu.Unlock()
无效尝试
常见但无效的做法:
-
Using recover() to catch panic and ignore
80% 失败
Recover hides the error but doesn't prevent data race or inconsistent state.
-
Checking ch != nil before close
100% 失败
A closed channel is not nil; nil check doesn't prevent double close.