[golang學習] goroutine調度

這兩天有些閒功夫, 學習下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在後續版本中應該會持續改進調度器.

相關文章
相關標籤/搜索