子 Goroutine パニックから回復するメカニズムは何ですか?
Go におけるパニック処理は、ランタイム エラーを管理するための重要な側面です。 goroutine のようなマルチスレッド環境では、子 goroutine で発生したパニックから呼び出し側関数を効果的に回復するにはどうすればよいかという疑問が生じます。
最初は、Goroutine でのパニックが発生すると必然的にプログラムが終了するように見えるかもしれませんが、特に、パニックが発生する前に呼び出し側関数の実行が終了した場合はそうです。ただし、簡単な例はそうではないことを示しています。
<code class="go">func fun1() { defer func() { if err := recover(); err != nil { fmt.Println("recover in func1") } }() go fun2() time.Sleep(10 * time.Second) fmt.Println("fun1 ended") } func fun2() { time.Sleep(5 * time.Second) panic("fun2 booom!") fmt.Println("fun2 ended") }</code>
この例では、呼び出し元関数 fun1 は、潜在的なパニックから回復するために呼び出しを延期します。驚くべきことに、fun2 がパニックになる前に fun1 が実行を終了したとしても、プログラムは終了せず、fun1 の遅延回復メカニズムはアクティブになりません。なぜそうなるのですか?
Go 仕様で答えが得られます:
今後の Go 仕様の抜粋
仕様によると、パニックが発生したとき関数内では、現在の関数の実行が終了し、その関数の遅延関数が通常どおり実行されます。続いて、呼び出し元関数の遅延関数(ゴルーチンの最上位関数まで)も実行されます。 ただし、ゴルーチンの最上位関数でパニックが発生した場合、プログラムは終了し、エラー状態が報告されます。
上記の例では、fun2 が最上位です。パニックを起こすゴルーチンのレベル関数。 fun2 には遅延回復メカニズムがないため、呼び出し元関数 fun1 に遅延回復メカニズムが存在するかどうかに関係なく、パニックが発生するとプログラムは終了します。
この動作は、ゴルーチンが回復できないという基本的な制限を浮き彫りにします。他のゴルーチンで発生するパニックから。各ゴルーチンには独自の独立した実行コンテキストがあり、あるゴルーチンの例外やエラーを別のゴルーチンで処理することはできません。したがって、各ゴルーチン内で潜在的なパニックを適切に処理することが重要です。
以上がGo は子ゴルーチンのパニックをどのように処理しますか?また、子ゴルーチンを親から回復できないのはなぜですか?の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。