Go語言自帶了一個高效率的協程調度器,可以輕鬆處理並發任務,實現高效能的程式。在本文中,我們將深入了解Go語言中的協程調度器,並探討其實作、操作以及最佳化。
協程簡介
協程是一種輕量級的執行緒或稱為使用者狀態執行緒。它由程式設計師調度,而不是由作業系統調度。協程的特徵是非搶佔式,即只有在明確呼叫yield()函數時才會切換上下文。因此,協程的切換開銷非常小,可以輕鬆地建立和銷毀,而且可同時執行非常多的協程,以實現並發執行程式。
Go語言協程模型
Go語言採用的是M:N 協程模型,也就是多個使用者狀態執行緒 M,對應多個系統級執行緒 N 的關係。這種模型充分發揮了多核心CPU的優勢,同時減少了上下文的切換開銷,並提高了調度效能。
M表示作業系統線程,即物理線程,是作業系統調度的最小單位。而N則表示Go語言運行時系統(runtime)中的虛擬執行緒(goroutine),是實現並發的最小單位。 N個goroutine 會映射到M個執行緒上,在運行時由調度器調度。
協程調度器
協程調度器是Go語言執行時間系統中的核心元件,負責管理並調度多個協程執行任務。它是一個高等級的調度器,可以控制協程的運作和切換,實現協程的等級調度。在Go語言中,協程調度器額外使用了一種成為Goroutine的運作實體,可以更有效率地在協程中切換執行任務。
協程調度器實現原理
協程調度器實現的原理可以分為兩個層次:作業系統層面和Go語言運行時系統層面。
作業系統層面
作業系統層面上,協程調度器會在執行時間映射多個使用者執行緒到多個作業系統執行緒上,利用多核心CPU的平行運算能力。
Go語言協程模型中的M:N架構,即M表示作業系統執行緒(Machine),N表示Go語言的虛擬執行緒(N,代表Goroutine),在運行時由調度器管理調度。調度器的主要作用就是在每個作業系統執行緒上維護一個調度任務佇列,根據任務佇列中任務的優先權和調度演算法動態調度各個執行緒上的任務的執行,並管理執行緒資源。
Go語言運行時系統層面
在Go語言執行時間系統層面上,協程調度器使用了三種機制:調度器、調度器佇列和P。
調度器
Go語言的協程調度器由一個全域的調度器控制,它會維護調度器佇列、P佇列、自旋次數、調度演算法等。調度器會動態管理每個執行緒上的任務執行,以實現最佳化協程的執行效率。
調度器佇列
調度器佇列是調度器用來記錄所有等待調度的 Goroutine 的地方。在調度器將Goroutine 分配到P 上時,它會首先從隊列中尋找等待調度的Goroutine,如果找到了,則立即把它們放入P 的本地隊列,如果沒有找到,則新創建一個Goroutine並放到P的本地佇列中。
P
P 是一個處理器,用來執行 Goroutine,它所擁有的佇列就是本地佇列。 P 的數量由 GOMAXPROCS 環境變數所控制,如果不設置,Go程式預設使用機器的核心數。
Go調度器的最佳化
Go調度器有許多最佳化策略,以下是其中幾個:
以上是Go語言中的協程調度器詳解的詳細內容。更多資訊請關注PHP中文網其他相關文章!