调用者函数如何从子 Goroutine 的 Panics 中恢复?
之前,假设 Goroutine 中的 Panic 会终止程序如果其调用者在恐慌发生之前完成。然而,对示例代码进行实验却发现情况并非如此。
示例代码:
<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>
意外行为:
尽管如此期望调用函数的恢复机制能够处理 goroutine 的恐慌,整个程序仍然终止。
说明:
Go 规范指出:
当 fun2 是 goroutine 中执行的顶级函数,并且 fun2 没有从恐慌中恢复时,程序会在 fun2 恐慌时终止。
因为 fun2 是其 goroutine 中的顶级函数,并且它会终止不处理恐慌,程序会提前终止。
Goroutine 自治:
一个 Goroutine 无法从另一个 Goroutine 的恐慌中恢复。因此,当 fun2 发生恐慌时,fun1 中的延迟调用不会被调用。
结论:
调用函数无法从它创建的 goroutine 中的恐慌中恢复,除非 goroutine 显式恢复避免程序调用者终止之前的恐慌。
以上是Go 中的调用函数可以从子 Goroutine 的 Panic 中恢复吗?的详细内容。更多信息请关注PHP中文网其他相关文章!