Windows操作系統(tǒng)多核CPU內(nèi)核線程管理方法
Windows 內(nèi)核親緣性調(diào)度原理圖
圖 2 Windows 內(nèi)核親緣性調(diào)度原理圖。
那么控制線程在指定CPU 上運行的突破口就是修改Windows 內(nèi)核結構體KTHREAD 下的Affinity 域。然而Windows 內(nèi)核結構被放在虛擬內(nèi)存線性地址的高2G(不同版本W(wǎng)indows 下也可能是1G)地址空間,用戶模式下的應用程序是無法訪問這段內(nèi)存空間的,所以必須編寫Windows 驅(qū)動程序,來訪問Windows 內(nèi)核內(nèi)存空間, 這也是本文將要描述的重點。
3 線程管理服務系統(tǒng)
整個系統(tǒng)的結構如圖3 所示。該系統(tǒng)由兩大部分組成,分別是內(nèi)核模式下的管理服務系統(tǒng)設備驅(qū)動程序,和用戶模式下的管理服務系統(tǒng)應用程序。管理服務系統(tǒng)應用程序通過調(diào)用Win32 子系統(tǒng)API,向內(nèi)核下的管理服務系統(tǒng)驅(qū)動程序傳遞IRP,內(nèi)核收到IRP 后,跟據(jù)收到的IRP 的內(nèi)部信息,執(zhí)行相應的派遣函數(shù),對相應內(nèi)存進行讀寫,從而給管理服務系統(tǒng)應用程序提供可用的系統(tǒng)信息。
管理系統(tǒng)總體結構圖
圖3 管理系統(tǒng)總體結構圖。
3.1 內(nèi)核模式下讀取系統(tǒng)信息
線程管理服務系統(tǒng)驅(qū)動程序中,讀取系統(tǒng)信息的方法用到了微軟沒有公開文檔的內(nèi)核服務函數(shù),ZwQuerySystemInformATIon,這個函數(shù)被封裝在ntdll.dll模塊中,通過鏈接ntdll.lib 可得到此函數(shù)地址。通過一個枚舉量SystemProcessInformaTIon 來得到進程線程相關信息,填入到第二個輸入?yún)?shù)SYSTEM_PROCESS_INFORMATION結構中, 這樣就獲得了當前系統(tǒng)關于進程線程的信息。
3.2 內(nèi)核模式下枚舉系統(tǒng)進程線程
SYSTEM_PROCESS_INFORMATION結構中存儲了進程及其線程的所有相關信息,表1 列出了它的具體內(nèi)容,包括結構內(nèi)域的地址偏移, 數(shù)據(jù)類型和描述。
SYSTEM_PROCESS_INFORMATION的第一個DWORD型是下一個進程 SYSTEM_PROCESS_INFORMATION相對于當前結構地址的偏移量,可以通過地址偏移來遍歷所有的進程結構,當遇到某一個進程結構的0 x 0 0 0 0 處的DWORD 型值為0 時,說明這個結構體是系統(tǒng)內(nèi)最后一個結構體。線程管理服務在它的派遣函數(shù)中通過這種方式遍歷所有進程,從中提取有用的信息,填入兩個自定義結構體中。如圖 4 所示,描述了一個具有兩個線程的進程的數(shù)據(jù)結構,首先在MY_PROCESS_INFO 結構中填入進程的相關信息,然后根據(jù)此進程所有的線程數(shù),向系統(tǒng)申請足夠大的分頁內(nèi)存空間,PVOID 型指針指向的是第一個線程結構所在的地址空間,然后向線程結構體中_MY_THREAD_INFO 中填入線程信息,再由線程結構體中的PVOID 型指針指向第二個線程結構體所在的地址空間,以此類推,最后一個線程結構體的PVOID型指針指向NULL。這樣一個過程描述了一個進程及其所屬的所有線程的枚舉過程,通過對所有進程的遍歷,可以得到系統(tǒng)中的一個完整的進程線程表,存在一段分頁內(nèi)存中,這樣在應用程序中便可以得到這些信息。
表1 SYSTEM_PROCESS_INFORMATION 結構本文引用地址:http://www.ex-cimer.com/article/202482.htm linux操作系統(tǒng)文章專題:linux操作系統(tǒng)詳解(linux不再難懂)
評論