ホームページ  >  記事  >  バックエンド開発  >  Go言語によるコルーチンスケジューラの詳細説明

Go言語によるコルーチンスケジューラの詳細説明

王林
王林オリジナル
2023-06-05 20:40:321577ブラウズ

Go 言語には効率的なコルーチン スケジューラが付属しており、同時タスクを簡単に処理し、高パフォーマンスのプログラムを実装できます。この記事では、Go 言語のコルーチン スケジューラを詳しく調べ、その実装、操作、最適化について説明します。

コルーチンの概要

コルーチンは、軽量スレッドまたはユーザーモード スレッドです。これは、オペレーティング システムではなく、プログラマによってスケジュールされます。コルーチンの特徴は、非プリエンプティブであること、つまり、yield() 関数が明示的に呼び出された場合にのみコンテキストが切り替わることです。したがって、コルーチンの切り替えオーバーヘッドは非常に小さく、簡単に作成および破棄でき、多くのコルーチンを同時に実行してプログラムの同時実行を実現できます。

Go 言語のコルーチン モデル

Go 言語は、M:N コルーチン モデル、つまり、複数のシステム レベルのスレッド N の関係に対応する複数のユーザー モード スレッド M を採用します。このモデルは、マルチコア CPU を最大限に活用しながら、コンテキスト切り替えのオーバーヘッドを削減し、スケジューリングのパフォーマンスを向上させます。

M は、オペレーティング システムのスレッド、つまりオペレーティング システムのスケジューリングの最小単位である物理スレッドを表します。 N は Go 言語の実行システム (ランタイム) における仮想スレッド (ゴルーチン) を表し、同時実行を実現する最小単位です。 N 個のゴルーチンが M 個のスレッドにマップされ、実行時にスケジューラによってスケジュールされます。

コルーチン スケジューラ

コルーチン スケジューラは Go 言語ランタイム システムのコア コンポーネントであり、タスクを実行する複数のコルーチンの管理とスケジュールを担当します。コルーチンの実行と切り替えを制御し、コルーチンのレベルスケジューリングを実現する高レベルスケジューラです。 Go 言語では、コルーチン スケジューラは、ゴルーチンと呼ばれる追加の実行エンティティを使用します。これにより、コルーチン内の実行タスクをより効率的に切り替えることができます。

コルーチン スケジューラーの実装原理

コルーチン スケジューラーの実装原理は、オペレーティング システム レベルと Go 言語ランタイム システム レベルの 2 つのレベルに分けることができます。

オペレーティング システム レベル

オペレーティング システム レベルでは、コルーチン スケジューラは、マルチコア CPU の並列コンピューティング機能を利用して、実行時に複数のユーザー スレッドを複数のオペレーティング システム スレッドにマップします。

Go 言語のコルーチン モデルの M:N アーキテクチャ、つまり、M はオペレーティング システムのスレッド (Machine) を表し、N は Go 言語の仮想スレッド (N、Goroutine を表す) を表し、管理されます。実行時のスケジューラによって。スケジューラの主な機能は、各オペレーティング システム スレッドでスケジューリング タスク キューを維持し、タスク キュー内のタスクの優先順位とスケジューリング アルゴリズムに従って各スレッドでのタスクの実行を動的にスケジュールし、スレッド リソースを管理することです。

Go 言語ランタイム システム レベル

Go 言語ランタイム システム レベルでは、コルーチン スケジューラはスケジューラ、スケジューラ キュー、P の 3 つのメカニズムを使用します。

スケジューラ

Go言語のコルーチンスケジューラは、スケジューラキュー、Pキュー、スピン数、スケジューリングアルゴリズムなどを管理するグローバルスケジューラによって制御されます。スケジューラは各スレッドでのタスクの実行を動的に管理し、コルーチンの実行効率を最適化します。

スケジューラ キュー

スケジューラ キューは、スケジューラがスケジュールを待っているすべての Goroutine を記録する場所です。スケジューラが P に Goroutine を割り当てるとき、スケジューラはまずスケジューリングを待っている Goroutine をキューから探します。見つかった場合は、すぐに P のローカル キューに入れます。見つからない場合は、新しい Goroutine を作成して P のキューに入れます。ローカルキュー。

P

P は Goroutine を実行するために使用されるプロセッサであり、それが所有するキューはローカル キューです。 P の数は GOMAXPROCS 環境変数によって制御されます。設定されていない場合、Go プログラムはデフォルトでマシンのコア数を使用します。

Go スケジューラの最適化

Go スケジューラには多くの最適化戦略があり、以下にそのいくつかを示します:

  1. Work Stealing

特定の P キュー内のすべてのゴルーチンがブロックされると、Go スケジューラーは他の P キュー内のゴルーチンを検索し、一部を盗んで独自のキューに入れて実行します。この戦略により、すべての P に対して安定した負荷と負荷共有が保証されます。

  1. プリエンプション

Goroutine は実行中に自分自身にタイマーを設定できます。時間が経過したら、 runtime.Goexit を呼び出して、この Goroutine をアクティブにスケジュールできることをランタイムに伝えます。 。 Go スケジューラには、ゴルーチンが積極的に Goexit を呼び出さない場合のプリプリエンプション ポリシーもあります。 Go 1.13 より前は、GOMAXPROCS が 1 の場合にのみプリエンプションが可能でした。より多くの状況をサポートするためにアップグレードされました。

  1. ローカル ランキュー

異なるスレッド間のタスクの競合を減らすために、各スレッドは独自のローカル キューを持ち、各スレッドはローカル キューから優先順位を取得します。タスクを取得して実行します。ローカルキューが空の場合のみ、グローバルキューからタスクが取得されます。

概要

コルーチン スケジューラは、Go 言語における高パフォーマンスの同時実行性の重要なコンポーネントの 1 つです。タスクを実行する複数のコルーチンの管理とスケジュールを担当し、M:N コルーチン モデルを採用し、オペレーティング システム レベルと Go 言語ランタイム システム レベルで異なるメカニズムとアルゴリズムを使用して、コルーチンの効率的な実行とスケジューリングを保証します。同時に、Go スケジューラには、コルーチン プリエンプション、ローカル実行キュー、タスク スティーリングなどの多くの最適化戦略もあり、プログラムをより効率的に実行し、プログラムのパフォーマンスとスループットを向上させることができます。

以上がGo言語によるコルーチンスケジューラの詳細説明の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。

声明:
この記事の内容はネチズンが自主的に寄稿したものであり、著作権は原著者に帰属します。このサイトは、それに相当する法的責任を負いません。盗作または侵害の疑いのあるコンテンツを見つけた場合は、admin@php.cn までご連絡ください。