這是一個建立於 的文章,其中的資訊可能已經有所發展或是發生改變。
之前對golang的goroutine機制和runtime.GOMAXPROCS不是很理解,今天抽空研究了一下,學習了其他大牛的文章。把自己的理解寫下來。如有錯誤,請指正
golang的goroutine機制有點像線程池:
一、go 內部有三個對象: P對象(processor) 代表上下文(或者可以認為是cpu),M(work thread)代表背景工作執行緒,G對象(goroutine).
二、正常情況下一個cpu對象啟一個背景工作執行緒對象,線程去檢查並執行goroutine對象。碰到goroutine對象阻塞的時候,會啟動一個新的背景工作執行緒,以充分利用cpu資源。所有有時候線程對象會比處理器對象多很多
我們用如分別表示P、M、G
在單核情況下,所有goroutine運行在同一個線程(M0)中,每一個線程維護一個上下文(P),任何時刻,一個上下文中只有一個goroutine,其他goroutine在runqueue中等待。一個goroutine運行完自己的時間片後,讓出上下文,自己回到runqueue中(如左邊所示)。
當正在啟動並執行G0阻塞的時候(可以需要IO),會再建立一個線程(M1),P轉到新的線程中去運行。
當M0返回時,它會嘗試從其他線程中“偷”一個上下文過來,如果沒有偷到,會把goroutine放到global runqueue中去,然後把自己放入線程緩衝中。上下文會定時檢查global runqueue。
-------------------------------- 分割線 ---------------------------------------------
GO預設是使用一個CPU核的,除非設定runtime.GOMAXPROCS
那麼在多核環境下,什麼情況下設定runtime.GOMAXPROCS會比較好的提高速度呢?
適合於CPU密集型、並行度比較高的情景。如果是IO密集型,CPU之間的切換也會帶來效能的損失。