1.APC机制
線(xiàn)程是不能被“殺掉”、“掛起”、“恢復(fù)”的,線(xiàn)程在執(zhí)行的時(shí)候自己占據(jù)著CPU,別人怎么可能控制它呢?
舉個(gè)極端的例子:如果不調(diào)用API,屏蔽中斷,并保證代碼不出現(xiàn)異常,線(xiàn)程將永久占用CPU,何談控制呢?所以說(shuō)線(xiàn)程如果想“死",一定是自己執(zhí)行代碼把自己殺死,不存在“他殺”這種情況!
那如果想改變一個(gè)線(xiàn)程的行為該怎么辦呢?
可以給他提供一個(gè)函數(shù),讓它自己去調(diào)用,這個(gè)函數(shù)就是APC (Asyncroneus Procedure Call),即異步過(guò)程調(diào)用。
APC隊(duì)列
kd> dt KTHREADnt! KTHREAD...+0x034 ApcState _KAPC_STATE... kd> dt _kapc_state nt!_KAPC_STATE+0x000 ApcListHead //2個(gè)APC隊(duì)列用戶(hù)APC和內(nèi)核APC+0x010 Process //線(xiàn)程所屬或者所掛靠的進(jìn)程_KPROCESS+0x014 KernelApcInProgress //內(nèi)核APC是否正在執(zhí)行+0x015 KernelApcPending //是否有正在等待執(zhí)行的內(nèi)核APC 1=有+0x016 UserApcPending //是否有正在等待執(zhí)行的用戶(hù)APC 1=有用戶(hù)APC: APC函數(shù)地址位于用戶(hù)空間,在用戶(hù)空間執(zhí)行
內(nèi)核APC: APC函數(shù)地址位于內(nèi)核空間,在內(nèi)核空間執(zhí)行
+0x01c NormalRoutine 可以找到你提供APC函數(shù)在哪,并不完全等于APC函數(shù)的地址
如果我想改變一個(gè)線(xiàn)程:
當(dāng)前的線(xiàn)程什么時(shí)候會(huì)執(zhí)行我們提供的這些APC函數(shù)?
判斷是否有APC要執(zhí)行
如果有APC
處理apc函數(shù)KiDeliverApc,這里我門(mén)發(fā)現(xiàn)只有用戶(hù)的apc,其實(shí)內(nèi)核的apc是一定會(huì)處理的它會(huì)先處理內(nèi)核apc在處理用戶(hù)的apc。
KiServiceExit函數(shù):
這個(gè)函數(shù)是系統(tǒng)調(diào)用、異常或中斷返回用戶(hù)空間的必經(jīng)之路。
KiDeliverApc函數(shù):
負(fù)責(zé)執(zhí)行APC函數(shù)
總結(jié)
- 上一篇: 13.跨进程读写内存
- 下一篇: 2.备用APC队列