検索
ホームページバックエンド開発GolangGo 言語に GMP スケジューリング モデルが存在する理由の詳細な分析

なぜ Go には GMP スケジューリング モデルがあるのですか? Go言語にGMPスケジューリングモデルが存在する理由については、以下の記事で紹介していますので、ご参考になれば幸いです。

Go 言語に GMP スケジューリング モデルが存在する理由の詳細な分析

#GMP スケジューリング モデルは Go の本質であり、マルチスレッドの同時スケジューリング コルーチンの効率性の問題を合理的に解決します。

GMP とは

まず、各世代の GMP が何を指すのかを理解する必要があります。

  • G: Goroutine の略語は、スレッド上で実行されるコルーチンを指します。
  • M: Machine の略称。つまり、thead、thread、cyclic scheduling coroutine、execution のことです。
  • P: Processor の略語で、コルーチンをローカル キューに保存し、スレッドに休止状態ではない利用可能なコルーチンを提供するプロセッサを指します。プロセッサ P はコルーチンを取得したいと考えています。コルーチンはまず P から取得されるため、GMP モデル図は次のようになります。

一般的なプロセスは、スレッド M が P からコルーチンを取得することです。キュー コルーチンがロックを取得できない場合、グローバル キューからロックを取得するために競合します。 Go 言語に GMP スケジューリング モデルが存在する理由の詳細な分析

プロセッサ P

コルーチン G とスレッド M の構造については以前の記事で説明しましたが、ここではプロセッサ P を分析します。

関数

プロセッサ P はコルーチンのバッチを保存するため、スレッド M は、グローバル キューをめぐって他のスレッドと競合することなく、ロックせずにコルーチンからコルーチンを取得できます。 . プロセス内のコルーチンにより、コルーチンのスケジューリング効率が向上します。

ソース コード分析

p 構造体のソース コードは src\runtime\runtime2.go

にあり、いくつかの重要なフィールドが示されています。ここ。

type p struct {
   ...
   m           muintptr   // back-link to associated m (nil if idle)
   // Queue of runnable goroutines. Accessed without lock.
   runqhead uint32
   runqtail uint32
   runq     [256]guintptr
   runnext guintptr
   ...
}

m
    はプロセッサ
  • p が属するスレッドです runq
  • は格納するキューですコルーチン
  • runqhead
  • runqtail はキューの先頭ポインタと末尾ポインタを表します runnext
  • は次の実行可能なコルーチンを指します

Go 言語に GMP スケジューリング モデルが存在する理由の詳細な分析スレッド M とプロセッサ P はどのように連携するのでしょうか?

src\runtime\proc.go

には、スレッドによって実行される最初の関数である

schedule メソッドがあります。この関数では、スレッドは実行可能なコルーチンを取得する必要があります。コードは次のとおりです:

func schedule() {    
    ...
    // 寻找一个可运行的协程
    gp, inheritTime, tryWakeP := findRunnable() 
    ...
}
func findRunnable() (gp *g, inheritTime, tryWakeP bool) {
    // 从本地队列中获取协程
    if gp, inheritTime := runqget(pp); gp != nil {
       return gp, inheritTime, false
    }

    // 本地队列拿不到则从全局队列中获取协程
    if sched.runqsize != 0 {
       lock(&sched.lock)
       gp := globrunqget(pp, 0)
       unlock(&sched.lock)
       if gp != nil {
          return gp, false, false
       }
    }
}
ローカル キューからコルーチンを取得します
func runqget(pp *p) (gp *g, inheritTime bool) {
   next := pp.runnext // 队列中下一个可运行的协程
   if next != 0 && pp.runnext.cas(next, 0) {
      return next.ptr(), true
   }
   ...
}

ローカル キューにコルーチンがない場合、またはグローバル キュー どうすればよいですか? このままスレッドをアイドル状態にしておいたほうがよいでしょうか?

このとき、プロセッサ P はタスクを盗み、他のスレッドのローカル キューから一部のタスクを盗みます。これを、他のスレッドのプレッシャーを共有し、自分のスレッドの使用率を向上させると呼びます。

ソース コードは

src\runtime\proc.go\stealWork

にあります。興味があればご覧ください。

新しく作成したコルーチンはどこに割り当てるべきですか?

新しく作成されたコルーチンはローカル キューまたはグローバル キューに割り当てられるべきですか? スコア:

Go は新しいコルーチンの優先度が高いと考えているため、最初にローカルキューに入れて列に並びます。

    このチームのキューがいっぱいになると、グローバル キューに入れられます。
  • 実際のプロセスは次のとおりです。

P

    P をランダムに検索します。新しいコルーチンを P の
  1. runnext
  2. に入れます。これは、次にコルーチンが実行され、キューがジャンプされます。
  3. P のコルーチンがいっぱいの場合、グローバル キューに入れられます
  4. ソース コードは
  5. src にあります\runtime\proc.go \newproc
関数。

// Create a new g running fn.
// Put it on the queue of g's waiting to run.
// The compiler turns a go statement into a call to this.
func newproc(fn *funcval) {
   gp := getg()
   pc := getcallerpc()
   systemstack(func() {
      newg := newproc1(fn, gp, pc) // 创建新协程

      pp := getg().m.p.ptr()
      runqput(pp, newg, true) // 寻找本地队列放入

      if mainStarted {
         wakep()
      }
   })
}
結論

この記事では、最初に GMP スケジューリング モデルを紹介し、特にプロセッサ P とスレッド M がコルーチンを取得する方法を紹介します。

プロセッサ P は、コルーチンを取得するためのマルチスレッド排他の問題を解決し、コルーチンのスケジューリングの効率を向上させますが、コルーチンがローカル キューにあるかグローバル キューにあるかに関係なく、コルーチンは順次実行されるだけのようです。では、Go ではどうすればよいでしょうか? コルーチンの非同期および同時実行を実装するにはどうすればよいでしょうか?次の記事で分析を続けましょう(誰も読んでくれないでしょうが…)。

推奨学習:

Golang チュートリアル

以上がGo 言語に GMP スケジューリング モデルが存在する理由の詳細な分析の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。

声明
この記事は掘金社区で複製されています。侵害がある場合は、admin@php.cn までご連絡ください。
他の言語と他の言語:比較分析他の言語と他の言語:比較分析Apr 28, 2025 am 12:17 AM

goisastrongchoiceforprojectsingingingimplicity、andconcurrency、butmaylackinadvencedecosystemmaturity.1)

他の言語の静的イニシャル化装置に移動するinit関数を比較する他の言語の静的イニシャル化装置に移動するinit関数を比較するApr 28, 2025 am 12:16 AM

go'sinit functionandjava'sstaticInitializerserserservetosetupenmentseforeThemainfunction、buttheydifferinexecution andcontrol.go'sinitissimpleandpleandpleandautomatic、suftable forbasicasiccicsiccicsiccicsicciscicsupsupsbutsbutcanleadeadcoMplecticaticifoverseforedifuredifuredifuredifuredifuredifuredifuredifuredifuredifuredifured

goのinit関数の一般的なユースケースgoのinit関数の一般的なユースケースApr 28, 2025 am 12:13 AM

fortheInit functioningoareの場合:1)configurationfilesbemainprogramstarts、2)初期化Globalvariables、および3)running-checksSorvalidationseforetheprogramprocutess.theinitistomationaledemainforeThemainfunction、Makin

GOのチャネル:ゴルチン間コミュニケーションのマスターGOのチャネル:ゴルチン間コミュニケーションのマスターApr 28, 2025 am 12:04 AM

cannelsElcialing of renablingsefientive communication betweengoroutines

GOのラッピングエラー:エラーチェーンにコンテキストを追加しますGOのラッピングエラー:エラーチェーンにコンテキストを追加しますApr 28, 2025 am 12:02 AM

GOでは、エラーをラップし、エラーを介してコンテキストを追加できます。 1)エラーパッケージの新機能を使用して、エラーの伝播中にコンテキスト情報を追加できます。 2)fmt.errorfおよび%wを介してエラーをラッピングして問題を見つけるのを手伝ってください。 3)カスタムエラータイプは、より多くのセマンティックエラーを作成し、エラー処理の表現力を高めることができます。

GOで開発する際のセキュリティ上の考慮事項GOで開発する際のセキュリティ上の考慮事項Apr 27, 2025 am 12:18 AM

goooffersbustfeaturesforsecurecoding、butdevelopersmustimplementsecuritybestpracticive.1)usego'scryptageforsecuredathing.2)surncurrencywithranciationwithranizationprimitivestopreventraceconditions.3)sanitexe zeexerinputeterinpuptoravoidsqlinj

Goのエラーインターフェイスを理解しますGoのエラーインターフェイスを理解しますApr 27, 2025 am 12:16 AM

Goのエラーインターフェイスは、TypeErrorInterface {error()String}として定義され、エラー()メソッドを実装する任意のタイプをエラーと見なすことができます。使用の手順は次のとおりです。1。iferr!= nil {log.printf( "anerroroccurred:%v"、err)return}などのエラーを基本的にチェックおよびログエラー。 2。TypeMyErrorStruct {MSGSTRINGDETAILSTRING}などのより多くの情報を提供するカスタムエラータイプを作成します。 3.エラーラッパー(GO1.13以降)を使用して、元のエラーメッセージを失うことなくコンテキストを追加する、

同時GOプログラムでのエラー処理同時GOプログラムでのエラー処理Apr 27, 2025 am 12:13 AM

Effectivitive Handleerrorsinconconconcurentgoprograms、usechannelstocommunicateerrors、Implienterrorwatchers、Sunidertimeouts、usebufferedchannels、およびprovideclearerrormess.1)usechannelstopasserrors fromgoroutineStothemainctunction.2)Anerrorwatcherを実装します

See all articles

ホットAIツール

Undresser.AI Undress

Undresser.AI Undress

リアルなヌード写真を作成する AI 搭載アプリ

AI Clothes Remover

AI Clothes Remover

写真から衣服を削除するオンライン AI ツール。

Undress AI Tool

Undress AI Tool

脱衣画像を無料で

Clothoff.io

Clothoff.io

AI衣類リムーバー

Video Face Swap

Video Face Swap

完全無料の AI 顔交換ツールを使用して、あらゆるビデオの顔を簡単に交換できます。

ホットツール

Safe Exam Browser

Safe Exam Browser

Safe Exam Browser は、オンライン試験を安全に受験するための安全なブラウザ環境です。このソフトウェアは、あらゆるコンピュータを安全なワークステーションに変えます。あらゆるユーティリティへのアクセスを制御し、学生が無許可のリソースを使用するのを防ぎます。

ゼンドスタジオ 13.0.1

ゼンドスタジオ 13.0.1

強力な PHP 統合開発環境

mPDF

mPDF

mPDF は、UTF-8 でエンコードされた HTML から PDF ファイルを生成できる PHP ライブラリです。オリジナルの作者である Ian Back は、Web サイトから「オンザフライ」で PDF ファイルを出力し、さまざまな言語を処理するために mPDF を作成しました。 HTML2FPDF などのオリジナルのスクリプトよりも遅く、Unicode フォントを使用すると生成されるファイルが大きくなりますが、CSS スタイルなどをサポートし、多くの機能強化が施されています。 RTL (アラビア語とヘブライ語) や CJK (中国語、日本語、韓国語) を含むほぼすべての言語をサポートします。ネストされたブロックレベル要素 (P、DIV など) をサポートします。

SublimeText3 中国語版

SublimeText3 中国語版

中国語版、とても使いやすい

AtomエディタMac版ダウンロード

AtomエディタMac版ダウンロード

最も人気のあるオープンソースエディター