golang runtime實現多核並行任務

來源:互聯網
上載者:User
這是一個建立於 的文章,其中的資訊可能已經有所發展或是發生改變。

    首先我們需要明確一下並行跟並發的區別,並發一般是被核心通過時間片或者中斷來控制的,遇到io阻塞或者時間片用完的時會轉移線程的使用權。一個核的情況下不可能有並行的情況,因為同一時間只有一個任務在調度。  


該文章寫的有些亂,歡迎來噴 ! 另外文章後續不斷更新中,請到原文地址查看更新。

http://xiaorui.cc/2016/03/05/golang-runtime%E5%AE%9E%E7%8E%B0%E5%A4%9A%E6%A0%B8%E5%B9%B6%E8%A1%8C%E4%BB%BB%E5%8A%A1/


    Golang預設所有的任務都在一個cpu核裡,如果想使用多核來跑goroutine的任務,需要配置runtime.GOMAXPROCS。 GOMAXPROCS的數目根據自己任務量分配就可以了,有個前提是不要大於你的cpu核心數。 並行比較適合那種cpu密集型計算,如果是IO密集型使用多核的化會增加cpu切換的成本。

Pythonpackage main//xiaorui.ccimport ("fmt""runtime")func test(c chan bool, n int) {x := 0for i := 0; i < 1000000000; i++ {x += i}println(n, x)if n == 10 {c <- true}}func main() {runtime.GOMAXPROCS(3)c := make(chan bool)for i := 0; i < 200; i++ {go test(c, i)}<-cfmt.Println("main end...")}
12345678910111213141516171819202122232425262728293031323334  package main//xiaorui.cc import ("fmt""runtime") func test(c chan bool, n int) { x := 0for i := 0; i < 1000000000; i++ {x += i}println(n, x)if n == 10 {c <- true}} func main() {runtime.GOMAXPROCS(3)c := make(chan bool) for i := 0; i < 200; i++ {go test(c, i)} <-c fmt.Println("main end...") }

對於經常使用python multiprocessing多進程模組來跑多核多任務的我來說,不再有GIL全域鎖是個很美妙的事情。   我們通過top可以看到上面的執行個體代碼跑到了cpu 270% . 跟我們上面配置的runtime.GOMAXPROCS(3)相對應。 

對於goroutine任務的終止也是有技巧的,他不能像多進程那樣,直接給kill掉。  他只能是通過類似flag訊號控制,每個goroutine執行的函數邏輯裡都要判斷flag標示位是否為stop狀態。

需要特意說明一點是,你在測試並發的時候,往往會把一個函數寫成死迴圈並做計算,你雖然這段函數用go關鍵詞並發了,但是你會發現他無法執行後面的邏輯。你需要做的是配置多核,或者是time.Sleep()。  這是為什麼 ? Golang是自己管理調整goroutine,如果你的一個func始終不釋放資源,那麼其他的goroutine不會去搶奪資源。 當然這樣的情境只有在測試時候遇到,正常情境下不可能沒有中斷和堵塞的情況。 

Pythonpackage mainimport ("fmt""runtime"_ "time")var (flag = falsestr string)func xiaorui() {flag = truestr = "setup flag to true"}func main() {runtime.GOMAXPROCS(1)go xiaorui()//time.Sleep(1 * time.Second) // 理論來說,當我在xiaorui()把flag 改為true後,後面的邏輯會退出. for {if flag {break}}fmt.Println(str)}
12345678910111213141516171819202122232425262728293031  package main import ("fmt""runtime"_ "time") var (flag = falsestr  string) func xiaorui() {flag = truestr = "setup flag to true"} func main() {runtime.GOMAXPROCS(1)go xiaorui()//time.Sleep(1 * time.Second)       // 理論來說,當我在xiaorui()把flag 改為true後,後面的邏輯會退出. for {if flag {break}}fmt.Println(str)}


我們不斷的調整的runtime.GOMAXPROCS(num) ,會發現執行的速度越來越快,但不要超過你的cpu數,因為那是徒勞的。 同樣的代碼我用python multiprocessing pool也實現了一份,我在MAC和線上伺服器做過測試,效能要遠高於python。

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.