呼叫者函數如何處理子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) 是在子goroutine (fun2) 中的恐慌之前還是之後完成,程式都會終止。這就提出了一個問題:為什麼呼叫函數中的延遲恢復機制不能防止程式崩潰?
規範的解釋
根據Go 規範:
「執行函數F 時,對恐慌或運行時恐慌的明確調用會終止F 的執行。並報告錯誤情況,包括恐慌的參數值。中,我們觀察到:
當fun2 出現恐慌時,它會變成
由於fun2 沒有從恐慌中恢復,程序終止。 fun1 中的延遲調用不會被調用,因為恐慌發生在不同的 goroutine 中。以上是為什麼呼叫函數中的延遲「恢復」不能處理子 Goroutine 中的恐慌?的詳細內容。更多資訊請關注PHP中文網其他相關文章!