Go Playground と Go on Your Machine の相違点
Go Playground とローカル マシン上の Go のゴルーチンの動作を比較する場合、矛盾が生じる可能性があります。根本的な理由を明確にするために、具体的な例を詳しく見てみましょう。
Go プレイグラウンドでは、GOMAXPROCS が最初に 1 に設定されているため、指定したコードにより「プロセスに時間がかかりすぎました」エラーが生成されることが予想されます。これは、other() 関数内で作成されたゴルーチンが無限ループを実行し、メインのゴルーチンが続行して完了チャネルからデータを受信できなくなるためです。
ただし、ローカル マシンでは、GOMAXPROCS 値が設定されている可能性があります。より大きな数値 (利用可能な CPU コアの数など) に設定します。これにより、複数の goroutine を同時に実行できるようになります。あなたの場合、メインのゴルーチンは完了チャネルからデータを受信し、他のゴルーチンは無限ループを並列実行します。データを受信すると、他のゴルーチンがまだ実行中であるかどうかに関係なく、メインのゴルーチンが処理を続行し、プログラムを終了します。
この非決定的な動作は、Go メモリ モデルに固有のものです。明示的な同期メカニズムが使用されない限り、ゴルーチンの実行順序は保証されません。
説明:
Go プレイグラウンドでは、GOMAXPROCS が 1 に設定されます。これは、意味します。一度に実行できる goroutine は 1 つだけです。コードでは、メインの goroutine が main() 関数を実行し、other() 関数を実行する 2 番目の goroutine を作成します。その後、メインの goroutine はブロックされた Done チャネルで待機します。
一度に 1 つの goroutine だけを実行できるため、スケジューラは other() 関数の実行を継続することを選択します。この関数は、done チャネルで値を送信し、現在のゴルーチン (other()) とメインのゴルーチンの両方を実行可能にします。ただし、GOMAXPROCS=1.
Other() により、無限ループを実行する別の goroutine が起動されるため、スケジューラは other() を実行し続けます。スケジューラはこのゴルーチンの実行を選択しますが、ブロック状態に達するまでに永遠に時間がかかります。その結果、main() 関数は続行されず、プログラムが無期限に実行され、Go プレイグラウンドで「プロセスに時間がかかりすぎました」というエラーが表示されます。
ローカルでは、GOMAXPROCS は 1 より大きい可能性があります。これにより、複数の処理が可能になります。 goroutine を同時に実行します。 other() が Done チャネルにデータを送信すると、スケジューラはメインの goroutine に切り替えることができ、プログラムの終了と終了に進みます。他のゴルーチンがまだ実行中の場合でも、メインのゴルーチンが終了するとプログラムは終了します。
以上がGo プレイグラウンドとローカル マシンでゴルーチンの動作が異なるのはなぜですか?の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。