這兩天有些閒功夫, 學習下golang, 確實很是簡潔. golang
不過有些缺憾. 在個人測試中. golang的調度(goroutine)彷佛不是很是好. 源碼分析
func say(k int) { fmt.Println(k) } func main() { runtime.GOMAXPROCS(2) for i := 0; i < 100; i++ { go say(i) } for { } }
這段測試代碼是有bug的.學習
一開始我並無設置測試
runtime.GOMAXPROCS(2)
則因爲for循環致使主線程阻塞. 全部的goroutine都沒有機會執行. spa
我在詢問了某我的以後, 加上這句. 線程
這是設置go的os線程數. code
但這樣出來的結果就有點奇怪, 有時候會輸出100個k, 有時候會輸出50個k. 或者乾脆一個k都沒有. blog
爲何呢?隊列
由於咱們沒法控制goroutine會被分配在哪一個 os線程上. 源碼
因此惟一(我所能查閱到的資料) 的解決辦法是在for循環中主動交出控制權. 使同一個 os線程上的goroutine有機會被執行.
像下面這樣:
for {
runtime.GOMAXPROCS(2)
}
這裏有一篇詳細的關於go 調度器的解釋:
http://morsmachine.dk/go-scheduler
也就是golang 中的每一個os線程對應的goroutine隊列, 在某個線程阻塞時會發生切換. 切換到其餘其餘線程執行. 但這個每每發生在I/O和系統調用時.
那爲何純粹的for循環阻塞時 golang沒法把goroutine切換到其餘線程執行呢?
由於go本身實現的I/O和系統調用 內部會自動調用runtime.GOMAXPROCS(2)
以上沒有源碼分析做爲支持. 可能會有謬誤. 請告訴我.
golang在後續版本中應該會持續改進調度器.