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