Win32_3-线程控制--事件&信号量

事件

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; }

【Win32_3-线程控制--事件&信号量】事件达到线程同步
线程同步
//事件和临界区 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, LPSTRlpCmdLine, intnCmdShow) { // TODO: Place code here. DialogBox(hInstance, MAKEINTRESOURCE(IDD_DIALOG_MAIN), NULL, MainDlgProc); return 0; }

    推荐阅读