1、創建事件對象:信號
CreateEvent(NULL, TRUE, FALSE, NULL);
kd> dt _DISPATCHER_HEADER
ntdll!_DISPATCHER_HEADER
+0x000 Type : UChar
+0x001 Absolute : UChar
+0x002 Size : UChar
+0x003 Inserted : UChar
+0x004 SignalState : Int4B
+0x008 WaitListHead : _LIST_ENTRY
實驗代碼
#include <stdio.h>
#include <windows.h>
HANDLE hEvent;
DWORD WINAPI ThreadProc(LPVOID lpParameter)
{
::WaitForSingleObject(hEvent, INFINITE);
printf("ThreadProc函數開始執行\n");
return 0;
}
int main()
{
//創建事件
//默認安全屬性 對象類型 初始狀態 名稱
hEvent = ::CreateEvent(NULL, TRUE, FALSE, NULL);
//設置爲有信號
//SetEvent(hEvent);
//創建線程
::CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE)ThreadProc, NULL, 0, NULL);
getchar();
return 0;
}
CreateEvent第三個參數就是設置SignalState,TRUE爲1,FALSE爲0,我們可以將其設爲FALSE和TRUE並運行程序來觀察。
2、創建事件對象:類型
CreateEvent(NULL, TRUE, FALSE, NULL);
第二個參數爲創建事件對象的類型, TRUE 爲通知類型對象, FALSE爲事件同步對象,對應_DISPATCHER_HEADER的第一個成員。
實驗代碼:
#include <stdio.h>
#include <windows.h>
HANDLE hEvent;
DWORD WINAPI ThreadProc1(LPVOID lpParameter)
{
::WaitForSingleObject(hEvent, INFINITE);
printf("ThreadProc1函數開始執行\n");
return 0;
}
DWORD WINAPI ThreadProc2(LPVOID lpParameter)
{
::WaitForSingleObject(hEvent, INFINITE);
printf("ThreadProc2函數開始執行\n");
return 0;
}
DWORD WINAPI ThreadProc3(LPVOID lpParameter)
{
::WaitForSingleObject(hEvent, INFINITE);
printf("ThreadProc3函數開始執行\n");
return 0;
}
int main()
{
HANDLE hThread[3];
//創建事件
//默認安全屬性 對象類型 初始狀態 名稱
hEvent = ::CreateEvent(NULL, FALSE, TRUE, NULL);
//設置爲有信號
//SetEvent(hEvent);
//創建線程
hThread[0] = ::CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE)ThreadProc1, NULL, 0, NULL);
hThread[1] = ::CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE)ThreadProc2, NULL, 0, NULL);
hThread[2] = ::CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE)ThreadProc3, NULL, 0, NULL);
getchar();
return 0;
}
我們將第二個參數改成TURE或FALSE分別做實驗觀察運行結果。
3、SetEvent函數分析
SetEvent對應的內核函數KeSetEvent
<1>修改信號SignalState值爲1
<2>判斷對象類型
<3>如果類型爲通知類型對象(0), 喚醒所有等待狀態的線程
<4>如果類型爲同步類型對象(1), 從鏈表頭找到第一個