gopl-zh.github.com/ch9/ch9-08-3.md

24 lines
2.0 KiB
Markdown
Raw Normal View History

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