零基礎逆向工程37_Win32_10_事件_線程同步
阿新 • • 發佈:2017-11-20
hcl word security 臨界區 運行 創建 and ima har
1 內核對象
前面已經學過線程和互斥體兩個內核對象。此節講了事件這個內核對象。前面提出了內核對象這個概念,可能不太清晰,簡單來說內核對象就是系統層的東西。
1.1 小結內核對象:
進程、線程、事件、互斥體、文件、文件映射等。
1.2 事件內核對象的創建
HANDLE g_hEvent = CreateEvent(NULL, TRUE, FALSE, "XYZ");
HANDLE g_hMutex = CreateMutex(NULL,FALSE, "XYZ");
1.3 事件內核對象的獲取
HANDLE OpenEvent( DWORD dwDesiredAccess, // access BOOL bInheritHandle, // inheritance option LPCTSTR lpName // object name ); HANDLE g_hEvent = OpenEvent(EVENT_ALL_ACCESS, FALSE, "XYZ"); HANDLE g_hMutex = OpenMutex(MUTEX_ALL_ACCESS,FALSE, "XYZ");
1.4 內核對象的銷毀
BOOL CloseHandle(HANDLE hobj);
(1)、當沒有其他程序引用時,系統會銷毀內核對象(使用數量).
(2)、內核對象的生命周期,可能比創建它的對象要長.
2 事件對象
2.1 事件對象的創建
HANDLE CreateEvent( LPSECURITY_ATTRIBUTES lpEventAttributes, // 安全屬性 NULL時為系統默認 BOOL bManualReset, // TRUE 通過調用ResetEvent將事件對象標記為未通知 BOOL bInitialState, // TRUE 已通知狀態 FALSE未通知狀態 LPCTSTR lpName // 對象名稱 以NULL結尾的字符串 );
2.2 事件對象的控制
BOOL SetEvent(HANDLE hEvent);
2.3 關閉時間對象句柄
CloseHandle();
2.4 線程控制實驗:只讀形式的線程控制
HANDLE g_hEvent; HWND hEdit1; HWND hEdit2; HWND hEdit3; HWND hEdit4; HANDLE hThread1; HANDLE hThread2; HANDLE hThread3; HANDLE hThread4; DWORD WINAPI ThreadProc1(LPVOID lpParameter) { //創建事件 //默認安全屬性 手動設置未通知狀態(TRUE) 初始狀態未通知 沒有名字 g_hEvent = CreateEvent(NULL, TRUE, FALSE, NULL); HANDLE hThread[3]; //創建3個線程 hThread[0] = ::CreateThread(NULL, 0, ThreadProc2, NULL, 0, NULL); hThread[1] = ::CreateThread(NULL, 0, ThreadProc3, NULL, 0, NULL); hThread[2] = ::CreateThread(NULL, 0, ThreadProc4, NULL, 0, NULL); //設置文本框的值 SetWindowText(hEdit1,"1000"); //設置事件為已通知 SetEvent(g_hEvent); //等待線程結束 銷毀內核對象 WaitForMultipleObjects(3, hThread, TRUE, INFINITE); CloseHandle(hThread[0]); CloseHandle(hThread[1]); CloseHandle(hThread[2]); CloseHandle(g_hEvent); return 0; } DWORD WINAPI ThreadProc2(LPVOID lpParameter) { TCHAR szBuffer[10] = {0}; //當事件變成已通知時 WaitForSingleObject(g_hEvent, INFINITE); //讀取內容 GetWindowText(hEdit1,szBuffer,10); SetWindowText(hEdit2,szBuffer); return 0; } DWORD WINAPI ThreadProc3(LPVOID lpParameter) { TCHAR szBuffer[10] = {0}; //當事件變成已通知時 WaitForSingleObject(g_hEvent, INFINITE); //讀取內容 GetWindowText(hEdit1,szBuffer,10); SetWindowText(hEdit3,szBuffer); return 0; } DWORD WINAPI ThreadProc4(LPVOID lpParameter) { TCHAR szBuffer[10] = {0}; //當事件變成已通知時 WaitForSingleObject(g_hEvent, INFINITE); //讀取內容 GetWindowText(hEdit1,szBuffer,10); SetWindowText(hEdit4,szBuffer); return 0; }
3 線程同步
3.1 什麽是線程同步?
同步就是協同步調,按預定的先後次序進行運行。如:你說完,我再說。
如進程、線程同步,可理解為進程或線程A和B一塊配合,A執行到一定程度時要依靠B的某個結果,於是停下來,示意B運行;B依言執行,再將結果給A;A再繼續操作。
[摘自百度百科]
3.2 事件和臨界區
HANDLE g_hSet, g_hClear;
int g_Max = 10;
int g_Number = 0;
//生產者線程函數
DWORD WINAPI ThreadProduct(LPVOID pM)
{
for (int i = 0; i < g_Max; i++)
{
WaitForSingleObject(g_hSet, INFINITE);
g_Number = 1;
DWORD id = GetCurrentThreadId();
printf("生產者%d將數據%d放入緩沖區\n",id, g_Number);
SetEvent(g_hClear);
}
return 0;
}
//消費者線程函數
DWORD WINAPI ThreadConsumer(LPVOID pM)
{
for (int i = 0; i < g_Max; i++)
{
WaitForSingleObject(g_hClear, INFINITE);
g_Number = 0;
DWORD id = GetCurrentThreadId();
printf("----消費者%d將數據%d放入緩沖區\n",id, g_Number);
SetEvent(g_hSet);
}
return 0;
}
int main(int argc, char* argv[])
{
HANDLE hThread[2];
g_hSet = CreateEvent(NULL, FALSE, TRUE, NULL);
g_hClear = CreateEvent(NULL, FALSE, FALSE, NULL);
hThread[0] = ::CreateThread(NULL, 0, ThreadProduct, NULL, 0, NULL);
hThread[1] = ::CreateThread(NULL, 0, ThreadConsumer, NULL, 0, NULL);
WaitForMultipleObjects(2, hThread, TRUE, INFINITE);
CloseHandle(hThread[0]);
CloseHandle(hThread[1]);
//銷毀
CloseHandle(g_hSet);
CloseHandle(g_hClear);
return 0;
}
零基礎逆向工程37_Win32_10_事件_線程同步