內(nèi)核線(xiàn)程(Kernel-Level Thread ,KLT)
成都創(chuàng)新互聯(lián)是一家集網(wǎng)站建設(shè),常州企業(yè)網(wǎng)站建設(shè),常州品牌網(wǎng)站建設(shè),網(wǎng)站定制,常州網(wǎng)站建設(shè)報(bào)價(jià),網(wǎng)絡(luò)營(yíng)銷(xiāo),網(wǎng)絡(luò)優(yōu)化,常州網(wǎng)站推廣為一體的創(chuàng)新建站企業(yè),幫助傳統(tǒng)企業(yè)提升企業(yè)形象加強(qiáng)企業(yè)競(jìng)爭(zhēng)力??沙浞譂M(mǎn)足這一群體相比中小企業(yè)更為豐富、高端、多元的互聯(lián)網(wǎng)需求。同時(shí)我們時(shí)刻保持專(zhuān)業(yè)、時(shí)尚、前沿,時(shí)刻以成就客戶(hù)成長(zhǎng)自我,堅(jiān)持不斷學(xué)習(xí)、思考、沉淀、凈化自己,讓我們?yōu)楦嗟钠髽I(yè)打造出實(shí)用型網(wǎng)站。
輕量級(jí)進(jìn)程(Light Weight Process,LWP):輕量級(jí)進(jìn)程就是我們通常意義上所講的線(xiàn)程,由于每個(gè)輕量級(jí)進(jìn)程都由一個(gè)內(nèi)核線(xiàn)程支持,因此只有先支持內(nèi)核線(xiàn)程,才能有輕量級(jí)進(jìn)程
用戶(hù)線(xiàn)程與系統(tǒng)線(xiàn)程一一對(duì)應(yīng),用戶(hù)線(xiàn)程執(zhí)行如lo操作的系統(tǒng)調(diào)用時(shí),來(lái)回切換操作開(kāi)銷(xiāo)相對(duì)比較大
多個(gè)用戶(hù)線(xiàn)程對(duì)應(yīng)一個(gè)內(nèi)核線(xiàn)程,當(dāng)內(nèi)核線(xiàn)程對(duì)應(yīng)的一個(gè)用戶(hù)線(xiàn)程被阻塞掛起時(shí)候,其他用戶(hù)線(xiàn)程也阻塞不能執(zhí)行了。
多對(duì)多模型是可以充分利用多核CPU提升運(yùn)行效能的
go線(xiàn)程模型包含三個(gè)概念:內(nèi)核線(xiàn)程(M),goroutine(G),G的上下文環(huán)境(P);
GMP模型是goalng特有的。
P與M一般是一一對(duì)應(yīng)的。P(上下文)管理著一組G(goroutine)掛載在M(內(nèi)核線(xiàn)程)上運(yùn)行,圖中左邊藍(lán)色為正在執(zhí)行狀態(tài)的goroutine,右邊為待執(zhí)行狀態(tài)的goroutiine隊(duì)列。P的數(shù)量由環(huán)境變量GOMAXPROCS的值或程序運(yùn)行runtime.GOMAXPROCS()進(jìn)行設(shè)置。
當(dāng)一個(gè)os線(xiàn)程在執(zhí)行M1一個(gè)G1發(fā)生阻塞時(shí),調(diào)度器讓M1拋棄P,等待G1返回,然后另起一個(gè)M2接收P來(lái)執(zhí)行剩下的goroutine隊(duì)列(G2、G3...),這是golang調(diào)度器厲害的地方,可以保證有足夠的線(xiàn)程來(lái)運(yùn)行剩下所有的goroutine。
當(dāng)G1結(jié)束后,M1會(huì)重新拿回P來(lái)完成,如果拿不到就丟到全局runqueue中,然后自己放到線(xiàn)程池或轉(zhuǎn)入休眠狀態(tài)??臻e的上下文P會(huì)周期性的檢查全局runqueue上的goroutine,并且執(zhí)行它。
另一種情況就是當(dāng)有些P1太閑而其他P2很忙碌的時(shí)候,會(huì)從其他上下文P2拿一些G來(lái)執(zhí)行。
詳細(xì)可以翻看下方第一個(gè)參考鏈接,寫(xiě)得真好。
最后用大佬的總結(jié)來(lái)做最后的收尾————
Go語(yǔ)言運(yùn)行時(shí),通過(guò)核心元素G,M,P 和 自己的調(diào)度器,實(shí)現(xiàn)了自己的并發(fā)線(xiàn)程模型。調(diào)度器通過(guò)對(duì)G,M,P的調(diào)度實(shí)現(xiàn)了兩級(jí)線(xiàn)程模型中操作系統(tǒng)內(nèi)核之外的調(diào)度任務(wù)。整個(gè)調(diào)度過(guò)程中會(huì)在多種時(shí)機(jī)去觸發(fā)最核心的步驟 “一整輪調(diào)度”,而一整輪調(diào)度中最關(guān)鍵的部分在“全力查找可運(yùn)行G”,它保證了M的高效運(yùn)行(換句話(huà)說(shuō)就是充分使用了計(jì)算機(jī)的物理資源),一整輪調(diào)度中還會(huì)涉及到M的啟用停止。最后別忘了,還有一個(gè)與Go程序生命周期相同的系統(tǒng)監(jiān)測(cè)任務(wù)來(lái)進(jìn)行一些輔助性的工作。
淺析Golang的線(xiàn)程模型與調(diào)度器
Golang CSP并發(fā)模型
Golang線(xiàn)程模型
參考:
Goroutine并發(fā)調(diào)度模型深度解析手?jǐn)]一個(gè)協(xié)程池
Golang 的 goroutine 是如何實(shí)現(xiàn)的?
Golang - 調(diào)度剖析【第二部分】
OS線(xiàn)程初始棧為2MB。Go語(yǔ)言中,每個(gè)goroutine采用動(dòng)態(tài)擴(kuò)容方式,初始2KB,按需增長(zhǎng),最大1G。此外GC會(huì)收縮??臻g。
BTW,增長(zhǎng)擴(kuò)容都是有代價(jià)的,需要copy數(shù)據(jù)到新的stack,所以初始2KB可能有些性能問(wèn)題。
更多關(guān)于stack的內(nèi)容,可以參見(jiàn)大佬的文章。 聊一聊goroutine stack
用戶(hù)線(xiàn)程的調(diào)度以及生命周期管理都是用戶(hù)層面,Go語(yǔ)言自己實(shí)現(xiàn)的,不借助OS系統(tǒng)調(diào)用,減少系統(tǒng)資源消耗。
Go語(yǔ)言采用兩級(jí)線(xiàn)程模型,即用戶(hù)線(xiàn)程與內(nèi)核線(xiàn)程KSE(kernel scheduling entity)是M:N的。最終goroutine還是會(huì)交給OS線(xiàn)程執(zhí)行,但是需要一個(gè)中介,提供上下文。這就是G-M-P模型
Go調(diào)度器有兩個(gè)不同的運(yùn)行隊(duì)列:
go1.10\src\runtime\runtime2.go
Go調(diào)度器根據(jù)事件進(jìn)行上下文切換。
調(diào)度的目的就是防止M堵塞,空閑,系統(tǒng)進(jìn)程切換。
詳見(jiàn) Golang - 調(diào)度剖析【第二部分】
Linux可以通過(guò)epoll實(shí)現(xiàn)網(wǎng)絡(luò)調(diào)用,統(tǒng)稱(chēng)網(wǎng)絡(luò)輪詢(xún)器N(Net Poller)。
文件IO操作
上面都是防止M堵塞,任務(wù)竊取是防止M空閑
每個(gè)M都有一個(gè)特殊的G,g0。用于執(zhí)行調(diào)度,gc,棧管理等任務(wù),所以g0的棧稱(chēng)為調(diào)度棧。g0的棧不會(huì)自動(dòng)增長(zhǎng),不會(huì)被gc,來(lái)自os線(xiàn)程的棧。
go1.10\src\runtime\proc.go
G沒(méi)辦法自己運(yùn)行,必須通過(guò)M運(yùn)行
M通過(guò)通過(guò)調(diào)度,執(zhí)行G
從M掛載P的runq中找到G,執(zhí)行G
線(xiàn)程:
多線(xiàn)程是為了解決CPU利用率的問(wèn)題,線(xiàn)程則是為了減少上下文切換時(shí)的開(kāi)銷(xiāo),進(jìn)程和線(xiàn)程在Linux中沒(méi)有本質(zhì)區(qū)別,最大的不同就是進(jìn)程有自己獨(dú)立的內(nèi)存空間,而線(xiàn)程是共享內(nèi)存空間。
在進(jìn)程切換時(shí)需要轉(zhuǎn)換內(nèi)存地址空間,而線(xiàn)程切換沒(méi)有這個(gè)動(dòng)作,所以線(xiàn)程切換比進(jìn)程切換代價(jià)要小得多。
協(xié)程:
想要簡(jiǎn)單,又要性能高,協(xié)程就可以達(dá)到我們的目的,它是用戶(hù)視角的一種抽象,操作系統(tǒng)并沒(méi)有這個(gè)概念,主要思想是在用戶(hù)態(tài)實(shí)現(xiàn)調(diào)度算法,用少量線(xiàn)程完成大量任務(wù)的調(diào)度。
Goroutine是GO語(yǔ)言實(shí)現(xiàn)的協(xié)程,其特點(diǎn)是在語(yǔ)言層面就支持,使用起來(lái)十分方便,它的核心是MPG調(diào)度模型:M即內(nèi)核線(xiàn)程;P即處理器,用來(lái)執(zhí)行Goroutine,它維護(hù)了本地可運(yùn)行隊(duì)列;G即Goroutine,代碼和數(shù)據(jù)結(jié)構(gòu);S及調(diào)度器,維護(hù)M和P的信息。