ホームページ > バックエンド開発 > Golang > 呼び出し元関数の遅延「recover」が子ゴルーチンのパニックを処理しないのはなぜですか?

呼び出し元関数の遅延「recover」が子ゴルーチンのパニックを処理しないのはなぜですか?

Susan Sarandon
リリース: 2024-11-03 18:06:03
オリジナル
639 人が閲覧しました

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

呼び出し元関数が子ゴルーチンのパニックを処理する方法

以前は、呼び出し元関数が次の場合にゴルーチン内のパニックが発生するとプログラムが終了すると考えられていました。パニックが起きる前に終わった。ただし、最近のコード例では、そうでないことを示唆しています。

<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 仕様によると、次のようになります。

「関数 F の実行中に、パニックまたはランタイム パニックへの明示的な呼び出しにより、F の実行が終了します。その後、F によって遅延された関数はすべて通常どおり実行されます。次に、F の呼び出し元によって実行された遅延関数が実行されます。など、実行中のゴルーチンの最上位関数によって遅延されるまで、プログラムは終了し、パニックへの引数の値を含むエラー状態が報告されます。この終了シーケンスはパニックと呼ばれます。 "

コードへの適用

この仕様をコードに適用すると、次のことがわかります。

  • fun2 がパニックになると、
  • fun2 がパニックから回復しないため、プログラムは終了します。
  • パニックが別の goroutine で発生するため、fun1 の遅延呼び出しは呼び出されません。

結論

したがって、ゴルーチンは別のゴルーチンのパニックから回復できないことを理解することが重要です。子ゴルーチンがパニックになった場合、延期/回復メカニズムを使用してパニックを処理できるのはゴルーチン自体だけです。子ゴルーチンが回復しない場合、呼び出し元のステータスに関係なく、プログラム全体が終了します。

以上が呼び出し元関数の遅延「recover」が子ゴルーチンのパニックを処理しないのはなぜですか?の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。

ソース:php.cn
このウェブサイトの声明
この記事の内容はネチズンが自主的に寄稿したものであり、著作権は原著者に帰属します。このサイトは、それに相当する法的責任を負いません。盗作または侵害の疑いのあるコンテンツを見つけた場合は、admin@php.cn までご連絡ください。
著者別の最新記事
人気のチュートリアル
詳細>
最新のダウンロード
詳細>
ウェブエフェクト
公式サイト
サイト素材
フロントエンドテンプレート