Win32_3-事件&訊號量
阿新 • • 發佈:2018-12-18
事件
HANDLE CreateEvent( LPSECURITY_ATTRIBUTES lpEventAttributes, // 安全屬性 NULL時為系統預設 BOOL bManualReset, // TRUE 通過呼叫ResetEvent將事件物件標記為未通知 BOOL bInitialState, // TRUE 已通知狀態 FALSE未通知狀態 LPCTSTR lpName // 物件名稱 以NULL結尾的字串 );
控制事件
BOOL SetEvent(HANDLE 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; }
事件達到執行緒同步
執行緒同步
//事件和臨界區 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; }
訊號量
HANDLE CreateSemaphore(
LPSECURITY_ATTRIBUTES lpSemaphoreAttributes, //安全控制,一般直接傳入NULL。
LONG lInitialCount, //初始資源數量。0時不傳送訊號
LONG lMaximumCount, //最大併發數量。lInitialCount<=lMaximumCount
LPCTSTR lpName //訊號量的名稱,傳入NULL表示匿名訊號量
);
#include "stdafx.h"
#include "resource.h"
HANDLE hSemaphore;
HANDLE hThread[3];
HWND hEditSet;
HWND hEdit1;
HWND hEdit2;
HWND hEdit3;
DWORD WINAPI ThreadProc1(LPVOID lpParameter)
{
TCHAR szBuffer[10];
DWORD dwTimmer = 0;
WaitForSingleObject(hSemaphore, INFINITE);
while (dwTimmer < 100)
{
Sleep(100);
memset(szBuffer, 0, 10);
GetWindowText(hEdit1, szBuffer, 10);
sscanf(szBuffer, "%d", &dwTimmer);
dwTimmer++;
memset(szBuffer, 0, 10);
sprintf(szBuffer, "%d", dwTimmer);
SetWindowText(hEdit1, szBuffer);
}
ReleaseSemaphore(hSemaphore, 1, NULL);
return 0;
}
DWORD WINAPI ThreadProc2(LPVOID lpParameter)
{
TCHAR szBuffer[10];
DWORD dwTimmer = 0;
WaitForSingleObject(hSemaphore, INFINITE);
while (dwTimmer < 100)
{
Sleep(100);
memset(szBuffer, 0, 10);
GetWindowText(hEdit2, szBuffer, 10);
sscanf(szBuffer, "%d", &dwTimmer);
dwTimmer++;
memset(szBuffer, 0, 10);
sprintf(szBuffer, "%d", dwTimmer);
SetWindowText(hEdit2, szBuffer);
}
ReleaseSemaphore(hSemaphore, 1, NULL);
return 0;
}
DWORD WINAPI ThreadProc3(LPVOID lpParameter)
{
TCHAR szBuffer[10];
DWORD dwTimmer = 0;
WaitForSingleObject(hSemaphore, INFINITE);
while (dwTimmer < 100)
{
Sleep(100);
memset(szBuffer, 0, 10);
GetWindowText(hEdit3, szBuffer, 10);
sscanf(szBuffer, "%d", &dwTimmer);
dwTimmer++;
memset(szBuffer, 0, 10);
sprintf(szBuffer, "%d", dwTimmer);
SetWindowText(hEdit3, szBuffer);
}
ReleaseSemaphore(hSemaphore, 1, NULL);
return 0;
}
DWORD WINAPI ThreadBegin(LPVOID lpParameter)
{
TCHAR szBuffer[10];
DWORD dwMoney = 0;
hSemaphore = CreateSemaphore(NULL, 0, 3, NULL);
hThread[0] = ::CreateThread(NULL, 0, ThreadProc1, NULL, 0, NULL);
hThread[1] = ::CreateThread(NULL, 0, ThreadProc2, NULL, 0, NULL);
hThread[2] = ::CreateThread(NULL, 0, ThreadProc3, NULL, 0, NULL);
//開始準備紅包
while (dwMoney < 1000)
{
memset(szBuffer, 0, 10);
GetWindowText(hEditSet, szBuffer, 10);
sscanf(szBuffer, "%d", &dwMoney);
dwMoney++;
memset(szBuffer, 0, 10);
sprintf(szBuffer, "%d", dwMoney);
SetWindowText(hEditSet, szBuffer);
}
ReleaseSemaphore(hSemaphore, 2, NULL);
::WaitForMultipleObjects(3, hThread, TRUE, INFINITE);
::CloseHandle(hSemaphore);
return 0;
}
BOOL CALLBACK MainDlgProc(HWND hDlg, UINT uMsg, WPARAM wParam, LPARAM lParam)
{
BOOL bRet = FALSE;
switch (uMsg)
{
case WM_CLOSE:
{
EndDialog(hDlg, 0);
break;
}
case WM_INITDIALOG:
{
hEditSet = GetDlgItem(hDlg, IDC_EDIT_SET);
hEdit1 = GetDlgItem(hDlg, IDC_EDIT_1);
hEdit2 = GetDlgItem(hDlg, IDC_EDIT_2);
hEdit3 = GetDlgItem(hDlg, IDC_EDIT_3);
SetWindowText(hEditSet, "0");
SetWindowText(hEdit1, "0");
SetWindowText(hEdit2, "0");
SetWindowText(hEdit3, "0");
break;
}
case WM_COMMAND:
switch (LOWORD(wParam))
{
case IDC_BUTTON_BEGIN:
{
CreateThread(NULL, 0, ThreadBegin, NULL, 0, NULL);
return TRUE;
}
}
break;
}
return bRet;
}
int APIENTRY WinMain(HINSTANCE hInstance,
HINSTANCE hPrevInstance,
LPSTR lpCmdLine,
int nCmdShow)
{
// TODO: Place code here.
DialogBox(hInstance, MAKEINTRESOURCE(IDD_DIALOG_MAIN), NULL, MainDlgProc);
return 0;
}