首頁 > 後端開發 > Golang > 主體

為什麼呼叫函數中的延遲「恢復」不能處理子 Goroutine 中的恐慌?

Susan Sarandon
發布: 2024-11-03 18:06:03
原創
566 人瀏覽過

Why Doesn't a Deferred `recover` in a Caller Function Handle Panics in Child Goroutines?

呼叫者函數如何處理子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 無法從另一個 Goroutine 的恐慌中恢復是至關重要的。如果子 Goroutine 發生恐慌,只有該 Goroutine 本身可以使用延遲/恢復機制來處理恐慌。如果子 Goroutine 沒有恢復,整個程式都會終止,無論其呼叫者的狀態為何。

以上是為什麼呼叫函數中的延遲「恢復」不能處理子 Goroutine 中的恐慌?的詳細內容。更多資訊請關注PHP中文網其他相關文章!

來源:php.cn
本網站聲明
本文內容由網友自願投稿,版權歸原作者所有。本站不承擔相應的法律責任。如發現涉嫌抄襲或侵權的內容,請聯絡admin@php.cn
作者最新文章
熱門教學
更多>
最新下載
更多>
網站特效
網站源碼
網站素材
前端模板
關於我們 免責聲明 Sitemap
PHP中文網:公益線上PHP培訓,幫助PHP學習者快速成長!