Windows事件等待学习笔记(二)—— 线程等待与唤醒
Windows事件等待學(xué)習(xí)筆記(二)—— 線(xiàn)程等待與喚醒
- 要點(diǎn)回顧
- 等待與喚醒機(jī)制
- 可等待對(duì)象
- 可等待對(duì)象的差異
- 線(xiàn)程與等待對(duì)象
- 一個(gè)線(xiàn)程等待一個(gè)對(duì)象
- 實(shí)驗(yàn)
- 第一步:編譯并運(yùn)行以下代碼
- 第二步:在WinDbg中找到該進(jìn)程
- 第三步:查看線(xiàn)程信息
- 一個(gè)線(xiàn)程等待多個(gè)對(duì)象
- 實(shí)驗(yàn)
- 第一步:編譯并運(yùn)行以下代碼
- 第二步:在WinDbg中找到該進(jìn)程
- 第三步:查看線(xiàn)程信息
- 第四步:查看等待塊具體細(xì)節(jié)
- 等待網(wǎng)
- 總結(jié)
要點(diǎn)回顧
之前學(xué)習(xí)了如何自己實(shí)現(xiàn)臨界區(qū)以及什么是自旋鎖,這兩種同步方案在線(xiàn)程無(wú)法進(jìn)入臨界區(qū)時(shí)都會(huì)讓當(dāng)前線(xiàn)程進(jìn)入等待狀態(tài)。
一種是通過(guò)Sleep函數(shù)實(shí)現(xiàn)的,一種是通過(guò)讓當(dāng)前的CPU“空轉(zhuǎn)”實(shí)現(xiàn)的,但這兩種等待方式都有局限性:
思考:有沒(méi)有更加合理的等待方式,只有在條件成熟的時(shí)候才將當(dāng)前線(xiàn)程喚醒?
等待與喚醒機(jī)制
描述:在Windows中,一個(gè)線(xiàn)程可以通過(guò)等待一個(gè)或者多個(gè)可等待對(duì)象,從而進(jìn)入等待狀態(tài),另一個(gè)線(xiàn)程可以在某些時(shí)刻喚醒等待這些對(duì)象的其他線(xiàn)程
可等待對(duì)象
在Windbg中查看以下結(jié)構(gòu)體:
dt _KPROCESS
dt _KTHREAD
dt _KTIMER
dt _KSEMAPHORE
dt _KEVENT
dt _KMUTANT
dt _FILE_OBJECT
總結(jié)
可等待對(duì)象的差異
WaitForSingleObject(3環(huán))
↓
NtWaitForSingleObject(內(nèi)核)
↓
KeWaitForSingleObject(內(nèi)核) //核心功能
線(xiàn)程與等待對(duì)象
描述:一個(gè)線(xiàn)程可以等待一個(gè)對(duì)象,也可以等待多個(gè)對(duì)象
一個(gè)線(xiàn)程等待一個(gè)對(duì)象
實(shí)驗(yàn)
第一步:編譯并運(yùn)行以下代碼
#include <stdio.h> #include <windows.h>HANDLE hEvent[2];DWORD WINAPI ThreadProc(LPVOID lpParamter) {::WaitForSingleObject(hEvent[0], -1);printf("ThreadProc函數(shù)執(zhí)行\(zhòng)n");return 0; }int main(int argc, char* argv[]) {hEvent[0] = ::CreateEvent(NULL, TRUE, FALSE, NULL); //創(chuàng)建一個(gè)可等待對(duì)象 _KEVENT::CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE)ThreadProc, NULL, 0, NULL);getchar();return 0; }第二步:在WinDbg中找到該進(jìn)程
!process 0 0
第三步:查看線(xiàn)程信息
查看 _KTHREAD
查看 _KWAIT_BLOCK
一個(gè)線(xiàn)程等待多個(gè)對(duì)象
實(shí)驗(yàn)
第一步:編譯并運(yùn)行以下代碼
#include <stdio.h> #include <windows.h>HANDLE hEvent[2];DWORD WINAPI ThreadProc(LPVOID lpParamter) {::WaitForMultipleObjects(2, hEvent, FALSE, -1);printf("ThreadProc函數(shù)執(zhí)行\(zhòng)n");return 0; }int main(int argc, char* argv[]) {hEvent[0] = ::CreateEvent(NULL, TRUE, FALSE, NULL); //創(chuàng)建可等待對(duì)象hEvent[1] = ::CreateEvent(NULL, TRUE, FALSE, NULL); //創(chuàng)建可等待對(duì)象::CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE)ThreadProc, NULL, 0, NULL);getchar();return 0; }第二步:在WinDbg中找到該進(jìn)程
!process 0 0
第三步:查看線(xiàn)程信息
dt _KTHREAD 862b3340
共有兩個(gè)等待塊:
注意:此時(shí)WaitType字段的值仍是1,這是因?yàn)橹灰幸粋€(gè)對(duì)象滿(mǎn)足條件,當(dāng)前線(xiàn)程就可以被喚醒(詳見(jiàn)第一步代碼部分)
第四步:查看等待塊具體細(xì)節(jié)
代碼中創(chuàng)建的對(duì)象為 _KEVENT,所以 _KWAIT_BLOCK +0x00C Object 指向 _KEVENT +0x000 _DISPATCHER_HEADER
kd> dt _DISPATCHER_HEADER 0x86015db8 nt_400000!_DISPATCHER_HEADER+0x000 Type : 0 ''+0x001 Absolute : 0x21 '!'+0x002 Size : 0x4 ''+0x003 Inserted : 0x86 ''+0x004 SignalState : 0n0+0x008 WaitListHead : _LIST_ENTRY [ 0x862b33c8 - 0x862b33c8 ]WaitListHead:雙向鏈表,圈著所有等待塊的WaitListEntry
等待網(wǎng)
總結(jié)
總結(jié)
以上是生活随笔為你收集整理的Windows事件等待学习笔记(二)—— 线程等待与唤醒的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。
- 上一篇: Windows事件等待学习笔记(一)——
- 下一篇: Windows事件等待学习笔记(三)——