mirror of
https://github.com/gopl-zh/gopl-zh.github.com.git
synced 2024-11-24 15:18:57 +00:00
2.0 KiB
2.0 KiB
9.8.3. GOMAXPROCS
Go的調度器使用了一個叫做GOMAXPROCS的變量來決定會有多少個操作繫統的線程同時執行Go的代碼。其默認的值是運行機器上的CPU的核心數,所以在一個有8個核心的機器上時,調度器一次會在8個OS線程上去調度GO代碼。(GOMAXPROCS是前面説的m:n調度中的n)。在休眠中的或者在通信中被阻塞的goroutine是不需要一個對應的線程來做調度的。在I/O中或繫統調用中或調用非Go語言函數時,是需要一個對應的操作繫統線程的,但是GOMAXPROCS併不需要將這幾種情況計數在內。
你可以用GOMAXPROCS的環境變量呂顯式地控製這個參數,或者也可以在運行時用runtime.GOMAXPROCS函數來脩改它。我們在下面的小程序中會看到GOMAXPROCS的效果,這個程序會無限打印0和1。
for {
go fmt.Print(0)
fmt.Print(1)
}
$ GOMAXPROCS=1 go run hacker-cliché.go
111111111111111111110000000000000000000011111...
$ GOMAXPROCS=2 go run hacker-cliché.go
010101010101010101011001100101011010010100110...
在第一次執行時,最多同時隻能有一個goroutine被執行。初始情況下隻有main goroutine被執行,所以會打印很多1。過了一段時間後,GO調度器會將其置爲休眠,併喚醒另一個goroutine,這時候就開始打印很多0了,在打印的時候,goroutine是被調度到操作繫統線程上的。在第二次執行時,我們使用了兩個操作繫統線程,所以兩個goroutine可以一起被執行,以同樣的頻率交替打印0和1。我們必鬚強調的是goroutine的調度是受很多因子影響的,而runtime也是在不斷地發展演進的,所以這里的你實際得到的結果可能會因爲版本的不同而與我們運行的結果有所不同。
練習9.6: 測試一下計算密集型的併發程序(練習8.5那樣的)會被GOMAXPROCS怎樣影響到。在你的電腦上最佳的值是多少?你的電腦CPU有多少個核心?