Go のランタイムの奥深く、src/runtime/proc.go に埋もれていますファイルには、謎の無限 for ループが存在します。その明らかな無駄さは、多くの開発者を困惑させてきました。なぜそれが存在するのでしょうか?その目的を理解するには、セマンティクスとランタイム機構の複雑な網を解き明かす必要があります。
src/runtime/proc.go の main() の最後で、コードは独特のシーケンスに従います:
<code class="go">exit(0) for { var x *int32 *x = 0 }</code>
信じられない背景
終了呼び出し後の無限ループの存在は直観に反するように思えるかもしれません。 exit 呼び出しによってプログラムが終了するのに、なぜさらに実行する必要があるのでしょうか?答えは、「到達不能コード」の概念にあります。
Go ランタイム内では、コード パスに決して到達してはならないことを示す必要がある特定の状況が発生します。ランタイムは、これらのパスが実行されないようにさまざまな手段に依存していますが、これらのパスが不注意でトリガーされた場合に備えて、ランタイムにはバックアップ プランが用意されています。
パンデモニウム チェック
Before無限ループでは、パニック処理が無効になっているかどうかを確認するチェックが実行されます。そうでない場合、プログラムはパニック処理が再度有効になるまで「パーク」状態に入ります。これにより、適切なエラー処理が可能になります。
核オプション
ただし、パニック処理が無効になっている場合、無限ループは最後の手段になります。保護されたメモリ領域 (この場合、*x = 0) に 0 を割り当てると、セグメンテーション違反がトリガーされ、実質的にプログラムが終了します。
この一見役に立たないループは、フェイルセーフ メカニズムとして機能します。これにより、より適切な終了が不可能になった場合に、プログラムが無期限に実行され続けることがなくなります。メモリ保護ユニットのないシステムの場合、メモリのアドレス 0 に 0 を書き込むだけで CPU が停止します。
ランタイム ソース コードをトレースし、パニック処理とランタイム メカニズムの間の微妙な相互作用を把握することで、次のことが明らかになりました。この一見謎めいた無限ループの目的。これは、Go の堅牢なエラー処理と、そのランタイムの基礎となる複雑なメカニズムの一例です。
以上がGo のランタイムで「exit(0)」の後に無限ループが発生するのはなぜですか?の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。