動(dòng)態(tài)棧操作系統(tǒng)的線程一般都有固定的棧內(nèi)存(通常為2MB),而 Go 語(yǔ)言中的 goroutine 非常輕量級(jí),一個(gè) goroutine 的初始棧空間很小(一般為2KB),所以在 Go 語(yǔ)言中一次創(chuàng)建數(shù)萬(wàn)個(gè) goroutine 也是可能的 。并且 goroutine 的棧不是固定的,可以根據(jù)需要?jiǎng)討B(tài)地增大或縮小,Go 的 runtime 會(huì)自動(dòng)為 goroutine 分配合適的棧空間 。
goroutine調(diào)度操作系統(tǒng)內(nèi)核在調(diào)度時(shí)會(huì)掛起當(dāng)前正在執(zhí)行的線程并將寄存器中的內(nèi)容保存到內(nèi)存中,然后選出接下來(lái)要執(zhí)行的線程并從內(nèi)存中恢復(fù)該線程的寄存器信息,然后恢復(fù)執(zhí)行該線程的現(xiàn)場(chǎng)并開(kāi)始執(zhí)行線程 。從一個(gè)線程切換到另一個(gè)線程需要完整的上下文切換 。因?yàn)榭赡苄枰啻蝺?nèi)存訪問(wèn),所以這個(gè)切換上下文的操作開(kāi)銷較大,會(huì)增加運(yùn)行的cpu周期 。
區(qū)別于操作系統(tǒng)內(nèi)核調(diào)度操作系統(tǒng)線程,goroutine 的調(diào)度是Go語(yǔ)言運(yùn)行時(shí)(runtime)層面的實(shí)現(xiàn),是完全由 Go 語(yǔ)言本身實(shí)現(xiàn)的一套調(diào)度系統(tǒng)——go scheduler 。它的作用是按照一定的規(guī)則將所有的 goroutine 調(diào)度到操作系統(tǒng)線程上執(zhí)行 。
【go GMP】在經(jīng)歷數(shù)個(gè)版本的迭代之后,目前 Go 語(yǔ)言的調(diào)度器采用的是 GPM 調(diào)度模型 。

文章插圖
- G:表示 goroutine,每執(zhí)行一次
go f()就創(chuàng)建一個(gè) G,包含要執(zhí)行的函數(shù)和上下文信息 。 - 全局隊(duì)列(Global Queue):存放等待運(yùn)行的 G 。
- P:表示 goroutine 執(zhí)行所需的資源,最多有 GOMAXPROCS 個(gè) 。
- P 的本地隊(duì)列:同全局隊(duì)列類似,存放的也是等待運(yùn)行的G,存的數(shù)量有限,不超過(guò)256個(gè) 。新建 G 時(shí),G 優(yōu)先加入到 P 的本地隊(duì)列,如果本地隊(duì)列滿了會(huì)批量移動(dòng)部分 G 到全局隊(duì)列 。
- M:線程想運(yùn)行任務(wù)就得獲取 P,從 P 的本地隊(duì)列獲取 G,當(dāng) P 的本地隊(duì)列為空時(shí),M 也會(huì)嘗試從全局隊(duì)列或其他 P 的本地隊(duì)列獲取 G 。M 運(yùn)行 G,G 執(zhí)行之后,M 會(huì)從 P 獲取下一個(gè) G,不斷重復(fù)下去 。
- Goroutine 調(diào)度器和操作系統(tǒng)調(diào)度器是通過(guò) M 結(jié)合起來(lái)的,每個(gè) M 都代表了1個(gè)內(nèi)核線程,操作系統(tǒng)調(diào)度器負(fù)責(zé)把內(nèi)核線程分配到 CPU 的核上執(zhí)行 。
GOMAXPROCSGo運(yùn)行時(shí)的調(diào)度器使用
GOMAXPROCS參數(shù)來(lái)確定需要使用多少個(gè) OS 線程來(lái)同時(shí)執(zhí)行 Go 代碼 。默認(rèn)值是機(jī)器上的 CPU 核心數(shù) 。例如在一個(gè) 8 核心的機(jī)器上,GOMAXPROCS 默認(rèn)為 8 。Go語(yǔ)言中可以通過(guò)runtime.GOMAXPROCS函數(shù)設(shè)置當(dāng)前程序并發(fā)時(shí)占用的 CPU邏輯核心數(shù) 。(Go1.5版本之前,默認(rèn)使用的是單核心執(zhí)行 。Go1.5 版本之后,默認(rèn)使用全部的CPU 邏輯核心數(shù) 。)經(jīng)驗(yàn)總結(jié)擴(kuò)展閱讀
- 3 onps棧使用說(shuō)明——tcp、udp通訊測(cè)試
- Java安全之動(dòng)態(tài)加載字節(jié)碼
- 2 onps棧使用說(shuō)明——ping、域名解析等網(wǎng)絡(luò)工具測(cè)試
- Vue3實(shí)現(xiàn)動(dòng)態(tài)導(dǎo)入Excel表格數(shù)據(jù)
- Go實(shí)現(xiàn)棧與隊(duì)列基本操作
- 定位java程序中占用cpu最高的線程堆棧信息
- 手機(jī)動(dòng)態(tài)彩鈴是怎么設(shè)置的(自己手機(jī)的彩鈴能設(shè)置嗎)
- 1 onps棧使用說(shuō)明——API接口手冊(cè)
- Flask框架:運(yùn)用Ajax輪詢動(dòng)態(tài)繪圖
- 小白也會(huì) HTML 動(dòng)態(tài)愛(ài)心-詳細(xì)教程
