<p>fatal error: all goroutines are asleep - deadlock! 表明Go运行时检测到所有goroutine永久阻塞且无人可唤醒,必须立即分析panic日志中的goroutine堆栈,重点排查channel收发不匹配、sync.WaitGroup计数未归零、Mutex未释放或锁顺序不一致等问题。</p>

看到 fatal error: all goroutines are asleep - deadlock! 就该立刻停手——这不是卡顿,是 Go 运行时确认无人可唤醒后强制退出,所有 goroutine 已彻底静止,再等日志或加 time.Sleep 只会让问题更难定位。
看 panic 日志里的 goroutine 堆栈,不是“哪行报错”,而是“谁在等什么”
panic 输出末尾的 goroutine 列表是唯一可信线索,必须逐行扫:
-
maingoroutine 停在ch <- v或<-ch?说明 channel 收发没配对,要么发送方没人收,要么接收方没启动或已退出 - 停在
wg.Wait()?先查是否漏调wg.Add(),尤其注意闭包中传参是值还是指针——wg传值会导致wg.Done()在副本上执行,原始计数器永不归零 - 停在
mu.Lock()?说明锁没被释放,或持有锁的 goroutine 已 panic/退出但没 unlock;也可能是嵌套锁顺序不一致(A 先锁 mu1 再锁 mu2,B 反过来) - 一堆 goroutine 全卡在
runtime.chansend或runtime.gopark+chan receive?基本锁定是无缓冲 channel 单向阻塞,比如只发不收、或只收不发 - 出现
init函数里起的 goroutine,且堆栈显示它依赖另一个包的init完成?这种死锁不报 channel 相关信息,但会静默卡死
别指望 pprof,死锁发生时它根本用不上
/debug/pprof/goroutine 接口需要 HTTP server 正常响应,而死锁 panic 一触发,程序就立即终止,server 来不及处理请求。pprof 只适用于“程序没崩但不动了”的场景:
- 想用它,必须提前加
import _ "net/http/pprof"和go http.ListenAndServe("localhost:6060", nil) - 卡住但没 panic 时,立刻执行
curl 'http://localhost:6060/debug/pprof/goroutine?debug=2',重点过滤含chan receive、sync.(*Mutex).Lock的行 -
/debug/pprof/block对死锁帮助极小——它统计“耗时阻塞”,而死锁是“永久阻塞”,可能一秒就 panic,根本来不及积累 block 时间
用 go tool trace 还原状态变迁,比看堆栈更快定位源头
pprof 是快照,trace 能回放 goroutine 状态变化过程,一眼看出谁在等谁、等了多久、有没有被唤醒过:
立即学习“go语言免费学习笔记(深入)”;
- 启动前确保已导入
import _ "net/http/pprof",main 开头加go http.ListenAndServe("localhost:6060", nil) - 运行后执行
go tool trace http://localhost:6060/debug/trace?seconds=5下载trace.out - 执行
go tool trace trace.out,打开 Web UI → “Goroutine” 标签页 → 筛选状态为chan recv或chan send - 典型线索:某个 goroutine 长时间处于
chan recv,且没有对应 sender 出现;无缓冲 channel 最容易暴露这种问题
最容易被忽略的三个静音陷阱
channel 和 mutex 死锁有 panic 报错,但有些情况连 runtime 都检测不到,只会让 goroutine 静默停住:
-
sync.RWMutex的RLock()不可重入:同一 goroutine 连续调两次RLock(),第二次就会永久卡在runtime_SemacquireMutex,不报deadlock -
mu.Lock()后遇到 error 提前 return,忘了mu.Unlock();或defer mu.Unlock()写在 if 分支里,分支没进就漏掉 - 文件 I/O 操作(如
os.ReadFile)不会触发死锁 panic——它属于可唤醒等待,goroutine 仍被视作 running;你看到的“卡在读文件”,大概率是 channel/mutex/wg 问题被误归因


















