子 Goroutine 恐慌中的调用函数恢复
与普遍看法相反,goroutine 的恐慌并不一定会终止整个程序。这种误解源于这样的假设:调用者中的延迟恢复函数将处理恐慌。但是,如果调用者在 goroutine 中发生恐慌之前完成,则情况并非如此。
考虑以下示例:
<code class="go">func fun1() { fmt.Println("fun1 started") defer func() { if err := recover(); err != nil { fmt.Println("recover in func1") } }() go fun2() time.Sleep(10 * time.Second) // wait for the boom! fmt.Println("fun1 ended") } func fun2() { fmt.Println("fun2 started") time.Sleep(5 * time.Second) panic("fun2 booom!") fmt.Println("fun2 ended") }</code>
尽管调用者函数 (fun1) 完成执行,但如果 fun2 出现恐慌,程序仍会终止。发生这种情况是因为 Go 规范定义了当 Goroutine 中发生恐慌时:
在这种情况下,fun2 是 goroutine 中的顶级函数,它不会从恐慌中恢复。因此,程序终止。
关键点是:
一个 Goroutine 无法从另一个 Goroutine 发生的 Panic 中恢复。
以上是调用者函数可以从子 Goroutine 恐慌中恢复吗?的详细内容。更多信息请关注PHP中文网其他相关文章!