go
runtime_error
ai_generated
true
恐慌:向已关闭的通道发送数据(发送者在关闭后发送)
panic: send on closed channel (from sender after close)
ID: go/goroutine-close-channel-from-sender
80%修复率
86%置信度
0证据数
2024-11-01首次发现
版本兼容性
| 版本 | 状态 | 引入 | 弃用 | 备注 |
|---|---|---|---|---|
| 1.0 | active | — | — | — |
| 1.22 | active | — | — | — |
根因分析
发送者协程在另一个协程关闭通道后发送数据,通常由于竞态条件。
English
Sender goroutine sends to a channel after another goroutine has closed it, often due to race.
解决方案
-
85% 成功率 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) -
90% 成功率 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)
无效尝试
常见但无效的做法:
-
Using recover() to catch panic and log
90% 失败
Recover doesn't fix the race; data may be lost.
-
Checking channel length before send
95% 失败
len(ch) doesn't indicate closed state; send still panics.