本文主要介紹線程的調(diào)度激活機(jī)制(Scheduler Activations),主要內(nèi)容:
調(diào)度激活機(jī)制簡介
上行調(diào)用(upcall)
中斷處理(Interrupt)
一、 調(diào)度激活機(jī)制簡介
上一篇文章詳細(xì)闡述了用戶空間和內(nèi)核空間的線程實(shí)現(xiàn),各有優(yōu)劣,內(nèi)核線程在各方面都比較靈活,但是太慢,性能不高,經(jīng)常會(huì)出現(xiàn)請求在用戶空間和內(nèi)核空間的傳遞,
Operating SystemThread(4) 線程的調(diào)度激活機(jī)制(S
。那么如何在擁有內(nèi)核空間線程的靈活性的同時(shí)又提高性能呢。這就是Scheduler Activations機(jī)制要做的事情。該機(jī)制的主要目標(biāo)是在用戶空間模擬內(nèi)核空間的線程(從靈活性方面),這樣在當(dāng)一個(gè)進(jìn)程內(nèi)的一個(gè)用戶線程被block(比如發(fā)生缺頁異常)時(shí),不會(huì)導(dǎo)致整個(gè)進(jìn)程被block,這個(gè)進(jìn)程的內(nèi)的其他用戶線程還可以繼續(xù)運(yùn)行(類似于內(nèi)核線程)。
當(dāng)Scheduler Activations機(jī)制啟用時(shí),內(nèi)核會(huì)給每一個(gè)進(jìn)程分配一定數(shù)量的CPU(有可能是虛擬的,如果是多核系統(tǒng),有可能是真實(shí)的CPU)。這樣每一個(gè)進(jìn)程的運(yùn)行時(shí)系統(tǒng)(run-time system)就可以給自己的線程(user-space threads)分配這些cpu。
初始默認(rèn)的cpu數(shù)量是1
進(jìn)程可以箱內(nèi)核申請更多的cpu
進(jìn)程可以將不再使用的CPU歸還給內(nèi)核
內(nèi)核可以自己將不用的CPU自己回收
由此可見,這種機(jī)制下,進(jìn)程對(duì)于CPU來說依然還是單線程的,內(nèi)核依然不知道進(jìn)程擁有多少線程。示意圖如下。
二、上行調(diào)用(upcall)
上面闡釋了調(diào)度激活機(jī)制,那么是如何實(shí)現(xiàn)的,運(yùn)行時(shí)是如何給自己的線程分配cpu的,
電腦資料
《Operating SystemThread(4) 線程的調(diào)度激活機(jī)制(S》(http://m.msguai.com)。如何調(diào)度的,這個(gè)是通過上行調(diào)用(upcall)來完成的。在cpu中用戶空間為上層,內(nèi)核為下層層,常規(guī)調(diào)用應(yīng)該是上層調(diào)用下層,下層不應(yīng)該調(diào)用上層,upcall就是指內(nèi)核調(diào)用用戶空間。
上圖展示了upcall。并且用傳統(tǒng)應(yīng)用webui和bll的調(diào)用做了類比,upcall是不規(guī)范的,但是調(diào)度激活就是通過upcall實(shí)現(xiàn)的。
upcall具體做了什么?
內(nèi)核發(fā)現(xiàn)用戶進(jìn)程的一個(gè)線程被block了(比如調(diào)用了一個(gè)被block的system call,或者發(fā)生了缺頁異常。
內(nèi)核通過進(jìn)程的運(yùn)行時(shí)線程被block(還會(huì)告知被block的線程的詳細(xì)信息),這個(gè)就是upcall
進(jìn)程的運(yùn)行時(shí)系統(tǒng)接收到內(nèi)核發(fā)來的消息,得知自己的線程被block
運(yùn)行時(shí)系統(tǒng)先將當(dāng)前線程標(biāo)識(shí)為block(會(huì)保存在線程表-thread table)
運(yùn)行時(shí)系統(tǒng)從當(dāng)前線程表(thread table)選擇一個(gè)ready的線程進(jìn)行運(yùn)行
至此已經(jīng)完成了當(dāng)一個(gè)進(jìn)程內(nèi)的一個(gè)用戶線程被block(比如發(fā)生缺頁異常)時(shí),不會(huì)導(dǎo)致整個(gè)進(jìn)程被block,這個(gè)進(jìn)程的內(nèi)的其他用戶線程還可以繼續(xù)運(yùn)行(類似于內(nèi)核線程)。
當(dāng)內(nèi)核發(fā)現(xiàn)之前被block的線程可以run了,同樣會(huì)通過upcall通知運(yùn)行時(shí)系統(tǒng),運(yùn)行時(shí)系統(tǒng)要么馬上運(yùn)行該線程,要么把該線程標(biāo)志位ready放入線程表。
三、中斷處理
當(dāng)一個(gè)用戶線程在運(yùn)行的時(shí)候硬件產(chǎn)生了一個(gè)中斷(Interrupt),這個(gè)時(shí)候應(yīng)該怎么辦呢?
被中斷的進(jìn)程不關(guān)注這個(gè)中斷,這個(gè)時(shí)候被中斷的線程會(huì)繼續(xù)返回到中斷產(chǎn)生前的狀態(tài)繼續(xù)執(zhí)行
被中斷的進(jìn)程關(guān)注這個(gè)中斷,被中斷的線程會(huì)被掛起,至于運(yùn)行那個(gè)線程:被中斷的線程,新的ready線程還是其他線程,這個(gè)有運(yùn)行時(shí)系統(tǒng)決定