日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

(62)时钟中断切换线程,时间片管理, KiDispatchInterrupt

發(fā)布時間:2025/3/21 编程问答 26 豆豆
生活随笔 收集整理的這篇文章主要介紹了 (62)时钟中断切换线程,时间片管理, KiDispatchInterrupt 小編覺得挺不錯的,現(xiàn)在分享給大家,幫大家做個參考.

一、回顧

前面的課程,我們分析了API主動切換線程的流程,分析了 KiSwapContext 和 SwapContext 函數(shù),這兩個是切換線程的函數(shù)。分析了 KiSwapThread 函數(shù),功能是找到新的就緒線程。分析了 KiFindReadyThread 函數(shù),了解了操作系統(tǒng)如何根據(jù)線程優(yōu)先級來調(diào)度線程。

除了主動切換以外,時鐘中斷和異常也會導致線程切換。

這次課我們來學習另一種導致線程切換的情景 —— 時鐘中斷。

二、時鐘中斷

Windows系統(tǒng)每隔10-20毫秒會觸發(fā)一次時鐘中斷,可以調(diào)用 GetSystemTimeAdjustment 函數(shù)獲取準確數(shù)值。

時鐘中斷的中斷號是0x30,中斷請求級別IRQL是0,我們可以在IDT表里找到時鐘中斷處理函數(shù) KiStartUnexpectedRange 。

我們可以在IDA里跟一下 KiStartUnexpectedRange 的執(zhí)行流程,發(fā)現(xiàn)依次調(diào)用了以下函數(shù):

  • KiStartUnexpectedRange
  • KiEndUnexpectedRange
  • KiUnexpectedInterruptTail
  • HalBeginSystemInterrupt
  • HalEndSystemInterrupt
  • KiDispatchInterrupt
  • KiDispatchInterrupt 函數(shù)會根據(jù)當前線程剩余時間片和備用線程的情況來決定下一步的調(diào)用,這部分在逆向時詳細介紹。

    三、時間片 Quantum ,備用線程 NextThread

    當一個新的線程開始執(zhí)行時,初始化程序會在 _KTHREAD.Quantum 賦初始值,該值的大小由_KPROCESS.ThreadQuantum 決定,默認是6.


    KeUpdateRunTime

    每次時鐘中斷會調(diào)用KeUpdateRunTime函數(shù),該函數(shù)每次將當前線程 Quantum減少3個單位,如果減到0,則將KPCR.PrcbData.QuantumEnd的 值設(shè)置為非0。

    .text:0046A1B8 sub [ebx+_KTHREAD.Quantum], 3 ; 時間片 -3 .text:0046A1BC jg short loc_46A1D7 .text:0046A1BE cmp ebx, [eax+_KPCR.PrcbData.IdleThread] .text:0046A1C4 jz short loc_46A1D7 .text:0046A1C6 mov [eax+_KPCR.PrcbData.QuantumEnd], esp

    可以看出,一個線程初始狀態(tài)有6個時間片,每次中斷會把當前線程時間片減3,這意味著一個線程要經(jīng)過兩次時鐘中斷時間片才會用完。

    KiDispatchInterrupt

    KiDispatchInterrupt 函數(shù)會判斷當前線程時間片,如果 QuantumEnd 是非0,表明時間片用完,然后就會調(diào)用 KiQuantumEnd 函數(shù)重新設(shè)置時間片,然后執(zhí)行線程切換;如果時間片沒用完,但是存在備用線程 NextThread,那么也會發(fā)生切換:

    KiDispatchInterrupt 函數(shù)的主要功能已經(jīng)分析完了,其中有兩個函數(shù)還沒介紹,分別是 KiQuantumEnd 和 KiReadyThread 。


    KiQuantumEnd

    KiQuantumEnd 函數(shù)主要工作就是重新設(shè)置時間片:

    mov al, [eax+_EPROCESS.Pcb.ThreadQuantum] mov [esi+_ETHREAD.Tcb.Quantum], al ; 重新設(shè)置一下當前線程的時間片

    然后調(diào)用 KiFindReadyThread 找新的就緒線程作為函數(shù)返回值:

    movzx ecx, [esi+_ETHREAD.Tcb.NextProcessor] call @KiFindReadyThread@8 ; KiFindReadyThread(x,x) cmp eax, ebx jz short loc_428C4B

    KiReadyThread

    這個函數(shù)的作用是把舊線程 ETHREAD(ecx 傳參)添加到就緒鏈表里,關(guān)鍵代碼如下:

    .text:00429A40 loc_429A40: ; CODE XREF: KiReadyThread(x)+5E↑j .text:00429A40 ; KiReadyThread(x)+12A↑j .text:00429A40 mov [eax+_ETHREAD.Tcb.State], 1 ; 就緒狀態(tài) .text:00429A44 add eax, 60h ; ETHREAD + 0x60 是一個鏈表, WaitListEntry / SwapListEntry .text:00429A47 test bl, bl .text:00429A49 lea edx, _KiDispatcherReadyListHead[ecx*8] ; edx 指向?qū)獌?yōu)先級的鏈表頭 .text:00429A50 jz short loc_429A60 .text:00429A52 mov esi, [edx] ; 下一個線程.FLink .text:00429A54 mov [eax], esi ; ETHREAD.WaitListEntry.FLink 指向下一個線程 .text:00429A56 mov [eax+4], edx ; ETHREAD.WaitListEntry.BLink 指向鏈表頭 .text:00429A59 mov [esi+4], eax ; 下一個線程.BLink 指向 ETHREAD.WaitListEntry .text:00429A5C mov [edx], eax ; 鏈表頭.FLink = ETHREAD.WaitListEntry .text:00429A5E jmp short loc_429A6D 《新程序員》:云原生和全面數(shù)字化實踐50位技術(shù)專家共同創(chuàng)作,文字、視頻、音頻交互閱讀

    總結(jié)

    以上是生活随笔為你收集整理的(62)时钟中断切换线程,时间片管理, KiDispatchInterrupt的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。

    如果覺得生活随笔網(wǎng)站內(nèi)容還不錯,歡迎將生活随笔推薦給好友。