← 中文资源

简体中文版本

Go 在无缓冲 channel 上报 all goroutines are asleep

通过匹配发送与接收、增加缓冲或用带 default 的 select,解决 channel 死锁。

阅读英文原文

症状

当所有 goroutine 都阻塞在 channel 且无人可推进时,运行时以 fatal error: all goroutines are asleep - deadlock 终止程序。这发生在无缓冲发送没有就绪接收者、某 goroutine 在接收前退出,或 range 等待一个永不被关闭的 channel 时。消息是精确的:无法推进,程序无法继续。

诊断

列出该 channel 的所有发送与接收;增加缓冲或用带 default 的 select;仅由发送方 close。

grep -n "ch <-\|<-ch\|range ch\|close(ch)" main.go

根因

某 goroutine 因无人执行配对操作而永久阻塞在 channel 上,运行时检测到所有 goroutine 都在睡眠。

修复

让每次无缓冲发送都有就绪接收者;在生产快于消费的合理场景加缓冲;由发送方 close 使 range 终止;用带 default 或超时的 select 避免无限阻塞。

验证

运行程序确认不再出现死锁消息,并确认所有预期值都完成发送与接收。完成且数据正确即证明 channel 协议平衡。

常见陷阱

在接收方 close channel 或重复 close 会 panic;关闭应由发送方单一负责。