Golang使用一種稱為搶占式調(diào)度(Preemptive Scheduling)的調(diào)度策略。搶占式調(diào)度是指調(diào)度程序可以在一個(gè)任務(wù)執(zhí)行期間中斷并切換到另一個(gè)任務(wù)。
Golang的搶占式調(diào)度的原理如下:
Golang的調(diào)度器維護(hù)一個(gè)全局的運(yùn)行隊(duì)列(run queue),其中包含所有可運(yùn)行的goroutine(即任務(wù))。調(diào)度器會(huì)根據(jù)一定的策略從運(yùn)行隊(duì)列中選擇一個(gè)goroutine來(lái)執(zhí)行。
當(dāng)一個(gè)goroutine開(kāi)始執(zhí)行時(shí),調(diào)度器會(huì)將其分配給一個(gè)線程(稱為M,或machine),并且將該線程標(biāo)記為忙碌狀態(tài)。
當(dāng)一個(gè)goroutine執(zhí)行時(shí)間超過(guò)一定閾值(稱為時(shí)間片,或time slice)時(shí),調(diào)度器會(huì)在該goroutine暫停執(zhí)行時(shí),將其重新放回運(yùn)行隊(duì)列,并選擇另一個(gè)可運(yùn)行的goroutine執(zhí)行。
切換線程時(shí),調(diào)度器會(huì)在空閑線程池中選擇一個(gè)空閑的線程,將它標(biāo)記為忙碌狀態(tài),并將該線程分配給即將執(zhí)行的goroutine。
調(diào)度器還會(huì)根據(jù)一定的策略(如搶占點(diǎn))在特定情況下中斷正在執(zhí)行的goroutine,并將其切換到其他goroutine。這樣可以避免某個(gè)goroutine長(zhǎng)時(shí)間占用線程,導(dǎo)致其他goroutine無(wú)法得到執(zhí)行的情況。
總之,Golang的搶占式調(diào)度通過(guò)在goroutine執(zhí)行期間進(jìn)行切換,以實(shí)現(xiàn)高效地利用CPU資源和保證并發(fā)執(zhí)行的需求。調(diào)度器負(fù)責(zé)在合適的時(shí)機(jī)中斷正在執(zhí)行的goroutine,并在運(yùn)行隊(duì)列中選擇下一個(gè)可運(yùn)行的goroutine來(lái)執(zhí)行。這種調(diào)度策略可以提高程序的并發(fā)性和響應(yīng)性。