Goroutines 不是系統執行序
前篇提到 Goroutines 是輕量的執行序,但又不同,究竟哪裡不同?
OS threads 系統執行序
OS threads 有固定大小的記憶體 (2MB),作為執行序的 stack,用於系統切換執行序時暫存local variables。 這個大小非常尷尬,對小程序太大,對大程序太小。
系統有個 kernel function 叫做 scheduler ,每隔一小段時間就會切換執行序,這個動作需要將當下執行的 thread 的狀態寫入 memory,並從memory中恢復要被執行的 thread 的狀態,這個動作稱為 full (kernel) context switch,而這個動作是慢的。
Goroutines
Goroutines 的 stack 作用與前者同,不同之處在於可伸縮,初始為2KB,最大可到1GB (來源請求)。
Go runtime 擁有自己的 scheduler ,這項技術稱為 m:n scheduling,因為他讓 m 個 goroutines 在 n 個 OS threads 上多工運行。
Goroutines 何時運作是靠Go程序控制,不像 OS threads 需要被系統週期性地沉睡又喚醒,並且在沉睡喚醒之間不用做 kernel context switch,所以切換 goroutines 非常便宜。
GOMAXPROCS
GOMAXPROCS 是一個 runtime 變數,設定 Go runtime 會用到幾個 OS threads,也就是前面的 m。在Go 1.5 開始預設為核心數,之前預設為1。
直接下 go env
指令是看不到 GOMAXPROCS 的,要調整有兩個辦法,第一種是:
GOMAXPROCS=4 go run myprogram.go
第二種辦法是:
import (
"runtime"
)
func main() {
runtime.GOMAXPROCS(10) // set GOMAXPROCS to 10
// rest of your program
}