面試企業(yè) 深信服棋恼,百度斤彼,小米,嗶哩嗶哩蘸泻,好未來琉苇,跟誰學(xué),學(xué)而思悦施,網(wǎng)易并扇,騰訊,知乎抡诞,高德穷蛹,字節(jié),昼汗,新浪肴熏,蝦皮,Aibee顷窒。
題目解析 GOLANG ROADMAP社區(qū)
答案(溪尾)
G是Goroutine
的縮寫蛙吏,相當(dāng)于操作系統(tǒng)的進程控制塊(process control block)源哩。它包含:函數(shù)執(zhí)行的指令和參數(shù),任務(wù)對象鸦做,線程上下文切換励烦,字段保護,和字段的寄存器泼诱。
M是一個線程坛掠,每個M都有一個線程的棧。如果沒有給線程的棧分配內(nèi)存治筒,操作系統(tǒng)會給線程的棧分配默認(rèn)的內(nèi)存屉栓。當(dāng)線程的棧制定,M.stack->G.stack, M的PC寄存器會執(zhí)行G提供的函數(shù)耸袜。
P(處理器友多,Processor)是一個抽象的概念,不是物理上的CPU句灌。當(dāng)一個P有任務(wù)夷陋,需要創(chuàng)建或者喚醒一個系統(tǒng)線程去處理它隊列中的任務(wù)欠拾。P決定同時執(zhí)行的任務(wù)的數(shù)量胰锌,GOMAXPROCS
限制系統(tǒng)線程執(zhí)行用戶層面的任務(wù)的數(shù)量。
GO調(diào)度器的調(diào)度過程藐窄,首先創(chuàng)建一個G對象资昧,然后G被保存在P的本地隊列或者全局隊列(global queue)。這時P會喚醒一個M荆忍。P按照它的執(zhí)行順序繼續(xù)執(zhí)行任務(wù)格带。M尋找一個空閑的P,如果找得到刹枉,將G與自己綁定叽唱。然后M執(zhí)行一個調(diào)度循環(huán):調(diào)用G對象->執(zhí)行->清理線程->繼續(xù)尋找Goroutine。
在M的執(zhí)行過程中微宝,上下文切換隨時發(fā)生棺亭。當(dāng)切換發(fā)生,任務(wù)的執(zhí)行現(xiàn)場需要被保護蟋软,這樣在下一次調(diào)度執(zhí)行可以進行現(xiàn)場恢復(fù)镶摘。M的棧保存在G對象中,只有現(xiàn)場恢復(fù)需要的寄存器(SP,PC等)岳守,需要被保存到G對象凄敢。
如果G對象還沒有被執(zhí)行,M可以將G重新放到P的調(diào)度隊列湿痢,等待下一次的調(diào)度執(zhí)行涝缝。當(dāng)調(diào)度執(zhí)行時,M可以通過G的vdsoSP, vdsoPC 寄存器進行現(xiàn)場恢復(fù)。
P隊列 P有2種類型的隊列:
本地隊列:本地的隊列是無鎖的俊卤,沒有數(shù)據(jù)競爭問題嫩挤,處理速度比較高。
全局隊列:是用來平衡不同的P的任務(wù)數(shù)量消恍,所有的M共享P的全局隊列岂昭。
線程清理 G的調(diào)度是為了實現(xiàn)P/M的綁定,所以線程清理就是釋放P上的G狠怨,讓其他的G能夠被調(diào)度约啊。
主動釋放(active release):典型的例子是,執(zhí)行G任務(wù)時佣赖,發(fā)生了系統(tǒng)調(diào)用(system call)恰矩,這時M會處于阻塞(Block)狀態(tài)。調(diào)度器會設(shè)置一個超時時間憎蛤,來釋放P外傅。
被動釋放(passive release):如果系統(tǒng)調(diào)用發(fā)生,監(jiān)控程序需要掃描處于阻塞狀態(tài)的P/M俩檬。 這時萎胰,超時之后,P資源會回收棚辽,程序被安排給隊列中的其他G任務(wù)技竟。
本文由 GOLANG ROADMAP 發(fā)布!