无法在父协程中捕获子协程的panic
func main() {
// 希望捕获所有所有 panic
defer func () {
r := recover()
fmt.Println("捕获到子协程panic:",r)
}()
// 启动新协程
go func () {
panic(123)
}()
// 等待一下,不然协程可能来不及执行
time.Sleep(1 * time.Second)
fmt.Println("这条消息打印不出来")
}
输出
panic: 123
goroutine 6 [running]:
main.main.func2()
...
Process finished with exit code 2
- 可以看到
recover
没有成功执行,整个进程都退出了 - 所以开了新协程而且忘记了在协程中捕获
panic
的话,服务的进程就会因为某个未捕获的panic
而退出。 - 解决方法,使用结构体维护两个通道来处理
done
和panic
事件,外部使用select
来维护处理抛出panic
,这样外部就可以recover
了