線程切換的幾種條件
如果學過操作系統,那么很容易就知道會有以下方法
- 時間片用完
- 強制切換
- 異常處理
時間片切換
其實也叫輪轉調度算法,顧名思義當時間到達一定的時候,就會切換一個線程,接着運行,這樣就可以讓我們感受到我們的只有單核使用的程序卻沒有斷過。
而在Windows中,當時間片到達時候,會引起中斷異常也就是0x30
Windows系列操作系統的時間片一般為:10-20毫秒
如果要獲取當前的時鍾間隔值,可以使用:GetSystemTimeAdjustment
時鍾中斷的執行流程
主動切換
主要是KiSwapContext函數進行的
這里我在上一篇文章有逆向分析就不說了
線程切換TSS
在上一篇文章中,我們分析了KiSwapContext,所以我會直接說結論
線程切換的本質就是堆棧的切換,而新線程的堆棧存放_KTHREAD結構體中
而且我們知道,在SwapContext函數里,esp會減少0x210,而這0x210存放的是浮點寄存器的值,其上面就是我們熟悉的_Trap_Frame結構了
但是Windows和linux都沒有使用這個東西,而是采用的堆棧來保存線程的各種寄存器的值
fs切換
由於fs在0環指向的是KPCR,3環指向的是TEB,所以FS也會切換,如何切換看我上一篇文章
優先級切換
上面我們提到有3種情況會導致線程切換:
那么,上一篇文章我也有說KiFindReadThread是用來找到下一個要執行的線程的,那么是根據什么條件查找呢?
KiFindReadThread查找條件
由於有32個調度鏈表和1個空閑鏈表,KiFindReadyThread的查找方式是按照優先級來進行查找的:31...28....20..0
也就是有級別高的線程就直接指向級別高的了,就不會再去找級別低的了
如何讓查找效率變高?
如果沒有就緒線程怎么辦?
就會去空閑隊列中查找