首先咱們應該明確,並行和併發的區別,我以前文章中有詳細的解釋。概要說就是,併發通常都是被內核經過時間片或者中斷來控制的,一旦遇到IO阻塞或者時間片用完,就會轉移線程的使用權。單核不可能有並行,同一時間只能有一個任務在調度。ubuntu
Go中runtime.GOMAXPROCS能夠設置多核執行任務。並行比較適合cpu計算密集型。若是IO密集型使用多核反而會增長cpu切換的成本。併發
須要特地說明一點是,你在測試併發的時候,每每會把一個函數寫成死循環並作計算,你雖然這段函數用go關鍵詞併發了,可是你會發現他沒法執行後面的邏輯。你須要作的是配置多核,或者是time.Sleep()。 這是爲何 ? Golang是本身管理調整goroutine,若是你的一個func始終不釋放資源,那麼其餘的goroutine不會去搶奪資源。 固然這樣的場景只有在測試時候遇到,正常場景下不可能沒有中斷和堵塞的狀況。 函數
那爲什麼說設置的核心越多反而會下降性能?看下面代碼:oop
package main import( "fmt" "time" "runtime" ) var quit chan int = make(chan int) func loop(){ for i:=0 ;i<10000; i++{ fmt.Printf("%d\n", i) } quit <- 0 } func main(){ fmt.Println(runtime.NumCPU()) // 默認CPU核心數 time.Sleep(2*time.Second) a := 5000 t0 := time.Now() // 起點時間 //runtime.GOMAXPROCS(1) // 設置執行使用的核心數 for i:=1; i<= a; i++{ go loop() } for i:=0; i< a; i++{ <-quit } endTime := time.Since(t0) // 耗時 fmt.Println("運行時間", endTime) }
首先說明個人電腦是8核ubuntu , 其中runtime.GOMAXPROCS(1) 被註釋, 獲得的結果是 2m13s 。 性能
取消註釋,使用一個核心執行此程序,獲得的確實1m 20s。 (都是屢次執行取平均值)。 測試
此處還要注意點一點就是: Go默認執行使用的CPU核心數爲系統CPU最大核心。ui
有的碼友可能以爲是channel的問題, 多個協程同時寫入,帶來的併發問題。其實否則,此處瓶頸在於fmt,spa
因爲多個協程同時往stdout寫入, 縱然前面執行再快,最後仍是要單線程輸出到屏幕,致使的性能問題,若是fmt換爲其餘操做,就能夠顯示出GOMAXPROCS的好處。.net