等待链表_调度(准备运行)链表
文章目錄
- 前奏
- 等待鏈表
- 調度(等待被調用)鏈表
- 版本差異
- 總結:
- 跨進程操作
前奏
對于進程斷鏈,程序可以正常運行,原因是CPU執行與調度是基于線程的,進程斷鏈只是影響一些遍歷系統進程的API,并不會影響程序執行
對于線程斷鏈也是一樣的,斷鏈后在Windbg或者OD中無法看到被斷的掉的線程,但不影響其執行(仍然再跑)
(1.平時使用API查詢當前進程有幾個線程時,都從上圖中的這個鏈表中查出,把鏈斷掉后,影響了API查詢結果)
(2.CPU在調度線程時,切換線程時,并沒有使用這個鏈表)
線程三種狀態:就緒(準備運行),等待,運行
等待鏈表
在windbg中輸入:
(找等待鏈表指令:)
dd KiWaitListHead
它是一個雙向鏈表,所以兩個指針都有用,指向的是_KTHREAD(0x060)這個位置,所以我們都會使用這個地址-0x60來找到_KTHREAD或者ETHREAD
比如:線程調用了Sleep()或者WaitForSingleObject()等函數時,就掛到這個鏈表
正在運行中的線程存儲在KPCR中,就緒和等待的線程全在另外的33個鏈表中,一個等待鏈表,32個就緒(調度)鏈表:
這些鏈表都使用了_KTHREAD(0x060)這個位置,也就是說,線程在某一時刻,只能屬于其中一個圈
調度(等待被調用)鏈表
既然有32個鏈表,就要有32個鏈表頭
(找調度鏈表指令:)
dd KiDispatcherReadyListHead L70
這里存儲了32個雙向鏈表(因為有線程級別區分,所以并不是一個全局變量就能解決)的鏈表頭
版本差異
XP只有一個33個圈(1個等待鏈表,32個調度鏈表),也就是說上面這個數組只有一個,多核也只有一個。
win7也是一樣的只有一個圈,如果是64位的,那就有64個調度鏈表,再加一個等待鏈表,那就有65個圈
服務器版本:
KiWaitListHead(等待鏈表)整個系統只有一個,但KiDispatcherReadyListHead(調度鏈表)這個數組有幾個CPU就有幾組
總結:
1.正在運行的線程KPCR中
2.準備運行的線程在32個調度鏈表中(0-31級),KisDispatcherReadyListHead是一個數組存儲了32個鏈表頭
3.等待狀態的線程存等待鏈表中,KiWaitListHead存儲鏈表頭
4.這些圈都掛在一個相同的位置:_KTHREAD(0x060)
當前線程處于等待狀態時,掛在等待鏈表中;當前線程如果處于調度狀態,調度鏈表在那32個圈中其中一個,那32個調度鏈表也掛在0x060這個位置(所以有兩個名字,無論是在調度狀態還是等待狀態,所掛的位置偏移都是一樣)
跨進程操作
A進程中的線程代碼:
mov cr3,B.DirectoryTableBase //切換Cr3的值為B進程
mov eax,dword ptr ds:[0x12345678] //將進程B 0x12345678的值存入eax中
mov dword ptr ds:[0x00401234],eax //將數據存儲到0x00401234中
mov cr3,A.DirectoryTableBase //切換回Cr3的值
//此時在0x00401234中的數據還有嗎?
切換回A進程中后0x00401234中的數據已經不見了,A和B低2G線性地址對應的物理頁是幾乎不同搞得,高2G線性地址對應的物理頁是幾乎相同的
總結
以上是生活随笔為你收集整理的等待链表_调度(准备运行)链表的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: KPCR:CPU控制区(Processo
- 下一篇: 进程挂靠 详解