M P G
- M代表內(nèi)核線程或工作線程,P是Go代碼片段執(zhí)行的上下文環(huán)境,G代表Go代碼片段。一個(gè)M與一個(gè)P關(guān)聯(lián)后就形成了一個(gè)有效的G運(yùn)行環(huán)境。
- M
2.1 M的重要組成:
· g0,g的指針類型,一個(gè)特殊的goroutine,用于執(zhí)行一些運(yùn)行時(shí)任務(wù)
· curg,g的指針,當(dāng)前關(guān)聯(lián)的goroutine
· p,當(dāng)前關(guān)聯(lián)的P
· nextp,與關(guān)聯(lián)的P
· spinning,是否在尋找可運(yùn)行的G
· lockedg,綁定的某個(gè)特定的G
· mstartfunc,起始函數(shù),即待執(zhí)行的goroutine函數(shù)或運(yùn)行時(shí)任務(wù)
2.2 M在創(chuàng)建時(shí)會(huì)被加入runtime.allm,并被設(shè)置起始函數(shù)和與關(guān)聯(lián)P。運(yùn)行時(shí)M會(huì)在執(zhí)行GC時(shí)被停止,并被放入調(diào)度器的空閑m列表,runtime.sched.midle。引導(dǎo)程序會(huì)把M的最大數(shù)量初始值設(shè)為10000,通過runtime.setMaxThreads可以重新設(shè)置,新值比舊值小會(huì)引發(fā)運(yùn)行時(shí)恐慌。 - P
3.1 P數(shù)量可以通過runtime.GOMAXPROCS(4)設(shè)置或GOMAXPROCS環(huán)境變量設(shè)置
3.2 引導(dǎo)程序?qū)設(shè)置的默認(rèn)值與cpu核心數(shù)相同
3.3 runtime.allp存放著所有P,runtime.sched.pidle存放著空閑P
3.4 P的狀態(tài)
· Pidle,未與任何M關(guān)聯(lián)
· Prunning,正在與某個(gè)M關(guān)聯(lián)
· Psyscall,P中運(yùn)行的G正在進(jìn)行系統(tǒng)調(diào)用
· Pgcstop,運(yùn)行時(shí)系統(tǒng)需要停止調(diào)度
· Pdead,P已不在被使用,當(dāng)GOMAXPROCS減小時(shí),多余的P是這個(gè)狀態(tài)
3.5 P中除了包含可運(yùn)行G列表,還有自由G列表,這里面是一些已經(jīng)完成運(yùn)行的G,當(dāng)P的自由G列表過長(zhǎng)時(shí),會(huì)移一部分到調(diào)度器的自由G列表中,程序中g(shù)o語(yǔ)句要新起一個(gè)G時(shí)會(huì)從P和調(diào)度器的自由G中找一個(gè)復(fù)用,如果沒有再新建一個(gè)G - G
4.1 go語(yǔ)句內(nèi)部是通過newproc函數(shù)實(shí)現(xiàn)的
4.2 所有G也都在runtime.allgs中
4.3 G的狀態(tài):
· Gidle,G剛分配還未初始化
· Grunnable,G在可運(yùn)行隊(duì)列中等待運(yùn)行
· Grunning,正在運(yùn)行
· Gsyscall,正在進(jìn)行系統(tǒng)調(diào)用
· Gwaiting,阻塞
· Gdead,閑置,處于此狀態(tài)的G可以被重用,會(huì)被放到自由G列表
· Gcopystack,棧正被擴(kuò)展或收縮
· Gscan與上面的組合,表示正在執(zhí)行運(yùn)行時(shí)監(jiān)控或GC - runtime
· runtime.allm; runtime.allp; runtime.allgs;
· runtime.sched.midle; pidle; gidle; runqhead; runqtail; gfreeStack; gfreeNoStack
· runtime.p.runq; runtime.p.gfree
調(diào)度器
- 配合gc等串行任務(wù)的字段
· gcwaiting,是否需要因一些任務(wù)停止調(diào)度
· stopwait,需要停止但未停止的P數(shù)量
· stopnote,與stopwait相關(guān)的事件通知機(jī)制 - main是第一個(gè)用戶G,而負(fù)責(zé)運(yùn)行時(shí)任務(wù)的稱作運(yùn)行時(shí)G
- runtime的schedule函數(shù)代表一輪調(diào)度,首先判斷當(dāng)前M是否已與某個(gè)G鎖定,或者正有串行任務(wù)等待運(yùn)行,都沒有則努力為M找一個(gè)可運(yùn)行G,然后還要判斷這個(gè)G是否已經(jīng)與某個(gè)M鎖定
- go 調(diào)度器是同時(shí)運(yùn)行在若干個(gè)M之中的
- 系統(tǒng)監(jiān)測(cè)任務(wù)負(fù)責(zé)搶奪合適的P和G,并根據(jù)idle和delay來執(zhí)行GC和堆清掃
- 有一個(gè)G專門負(fù)責(zé)強(qiáng)制GC,