Go言語の協程スケジューリングの仕組み

Go言語のコルーチンはM:Nモデルに基づいてスケジュールされています。MはオペレーティングシステムのThreads、NはGo言語のコルーチンを表します。

Goのスケジューラーは、ひとつ以上のオペレーティングシステムスレッド(M)を作成し、Mには、実行待ちのゴルーチンを格納するための自身のローカルキューがあります。プログラムの起動時には、既定で、CPUコア数と同じ数のMが作成されます。

スケジューラは、コルーチンが実行されるべきときに、それをあるMのローカルキューに入れる。Mのローカルキューが空の場合、スケジューラはグローバルキューからコルーチンをバッチ取得し、それらをMのローカルキューに入れる。

M のローカルキューのゴルーチンが実行を完了すると、スケジューラーは他の M のローカルキューまたはグローバルキューからゴルーチンのバッチを取得し、M のローカルキューに追加します。

協程の実行中に IO 操作、システムコール、または協程の能動的な CPU 明け渡しという状況が発生すると、M は現在実行中の協程を待機キューに入れ、ローカルキューまたはグローバルキューから別の協程を取得して実行を継続します。

スケジューラーは各Mの実行状態(実行時間、ブロック時間など)を監視し、それらの情報に基づいて負荷分散を行い、ビジー状態のMからアイドル状態のMにコルーチンを移動させて、システム全体の性能を向上させます。

Goのgoroutineスケジューラは、M:Nモデルを用いて複数のgoroutineを少数個のOSスレッドに分散して実行し、キューイングやロードバランシングといった仕組みによって効率的な並行処理を実現しています。

bannerAds