golang runtime實現多核並行任務
golang runtime實現多核並行任務
首先我們需要明確一下並行跟併發的區別,併發一般是被核心通過時間片或者中斷來控制的,遇到io阻塞或者時間片用完的時會轉移執行緒的使用權。一個核的情況下不可能有並行的情況,因為同一時間只有一個任務在排程。
該文章寫的有些亂,歡迎來噴 ! 另外文章後續不斷更新中,請到原文地址檢視更新。
Golang預設所有的任務都在一個cpu核裡,如果想使用多核來跑goroutine的任務,需要配置runtime.GOMAXPROCS。 GOMAXPROCS的數目根據自己任務量分配就可以了,有個前提是不要大於你的cpu核數。 並行比較適合那種cpu密集型計算,如果是IO密集型使用多核的化會增加cpu切換的成本。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 |
package main //xiaorui.cc
import ( "fmt" "runtime" )
func test(c chan bool, n int) {
x := 0 for 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不會去搶奪資源。 當然這樣的場景只有在測試時候遇到,正常場景下不可能沒有中斷和堵塞的情況。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 |
package main
import ( "fmt" "runtime" _ "time" )
var ( flag = false str string )
func xiaorui() { flag = true str = "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。
相關文章
- 使用.NET並行任務庫(TPL)與並行Linq(PLINQ)充分利用多核效能並行
- Java多執行緒並行處理任務的實現Java執行緒並行
- 任務排程並行演算法的Java簡單實現並行演算法Java
- WRF WPS多核並行執行並行
- golang實現簡單的併發任務消費Golang
- Python 並行任務技巧Python並行
- 任務排程並行演算法的Python簡單實現並行演算法Python
- AsyncTask實現非同步任務執行非同步
- 溫故之.NET 任務並行並行
- 並行執行任務的Fork/Join框架並行框架
- PHP定時執行任務的實現PHP
- 編輯計劃任務並執行
- 一行程式碼完成並行任務行程並行
- Spring Boot整合quartz實現定時任務並支援切換任務資料來源Spring Bootquartz
- Golang——Cron 定時任務Golang
- 實現一個併發任務執行框架框架
- 任務排程的並行演算法並行演算法
- 在 Golang 中使用 Go 關鍵字和 Channel 實現並行Golang並行
- crontab+shell 實現每秒執行一個任務
- Python實現投遞多執行緒任務Python執行緒
- MemQ 實現非同步任務MQ非同步
- 定時任務的實現
- goroutine的多核並行化,讓出時間片Go並行
- Java Spring註解任務排程並實現AOP監控任務執行情況JavaSpring
- C#多執行緒開發-任務並行庫04C#執行緒並行
- 非同步任務:並行與序列的典型問題非同步並行
- .NET併發程式設計-任務函式並行程式設計函式並行
- laravel建立定時任務並在windows下執行LaravelWindows
- Golang 入門 : 等待 goroutine 完成任務Golang
- Java如何實現定時任務?Java
- redhat 9.0 中任務自動執行的實現方式 (轉)Redhat
- Java7提供的並行執行任務框架:Fork、Join框架Java並行框架
- Golang 實現 Redis(10): 本地原子性事務GolangRedis
- 用 Golang 實現百萬級 Websocket 服務GolangWeb
- golang實現的長連線服務Golang
- 任務:重現
- 關機提示 ”task host window任務宿主正在執行關閉任務並且正在停止已執行的任務“我是這樣解決的
- 基於REDIS實現延時任務Redis