呼び出し元関数が子ゴルーチンのパニックを処理する方法
以前は、呼び出し元関数が次の場合にゴルーチン内のパニックが発生するとプログラムが終了すると考えられていました。パニックが起きる前に終わった。ただし、最近のコード例では、そうでないことを示唆しています。
<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 の呼び出し元によって実行された遅延関数が実行されます。など、実行中のゴルーチンの最上位関数によって遅延されるまで、プログラムは終了し、パニックへの引数の値を含むエラー状態が報告されます。この終了シーケンスはパニックと呼ばれます。 "
コードへの適用
この仕様をコードに適用すると、次のことがわかります。
結論
したがって、ゴルーチンは別のゴルーチンのパニックから回復できないことを理解することが重要です。子ゴルーチンがパニックになった場合、延期/回復メカニズムを使用してパニックを処理できるのはゴルーチン自体だけです。子ゴルーチンが回復しない場合、呼び出し元のステータスに関係なく、プログラム全体が終了します。
以上が呼び出し元関数の遅延「recover」が子ゴルーチンのパニックを処理しないのはなぜですか?の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。