事件:
#include <Windows.h> #include <iostream> DWORD WINAPI Func1Pro(LPVOID lpParameter); DWORD WINAPI Func2Pro(LPVOID lpParameter); int tickets = 100; HANDLE g_hEvent; void main() { HANDLE hThread1; HANDLE hThread2; hThread1 = CreateThread(NULL, 0, Func1Pro, NULL, 0, NULL); hThread2 = CreateThread(NULL, 0, Func2Pro, NULL, 0, NULL); CloseHandle(hThread1); CloseHandle(hThread2); // g_hEvent = CreateEvent(NULL, TRUE, FALSE, NULL); //人工重置的事件对象, 初始信号状态设置为无信号状态 //g_hEvent = CreateEvent(NULL, FALSE, FALSE, NULL); //自动重置事件对象, 初始信号状态设置为无信号状态 g_hEvent = CreateEvent(NULL, FALSE, FALSE, "tickets"); if(g_hEvent) { //带名字的事件对象也是系统唯一的, 可以判断实例 if(ERROR_ALREADY_EXISTS == GetLastError()) { std::cout<< "only instance can run!" << std::endl; return; } } SetEvent(g_hEvent);//人工重置的事件对象, 会将所有线程的事件信号状态都改变 ResetEvent改成无信号 Sleep(4000); CloseHandle(g_hEvent); } DWORD WINAPI Func1Pro(LPVOID lpParameter) { while(TRUE) { WaitForSingleObject(g_hEvent, INFINITE); //如果是自动重置事件对象 处理时, 会改成非信号状态 if(tickets > 0) { Sleep(1); std::cout << "thread1 sell ticket: " << tickets-- << std::endl; } else break; SetEvent(g_hEvent); //再设置为有信号状态 } return 0; } DWORD WINAPI Func2Pro(LPVOID lpParameter) { while(TRUE) { WaitForSingleObject(g_hEvent, INFINITE);//如果是自动重置事件对象 处理时, 会改成非信号状态 if(tickets > 0) { Sleep(1); std::cout << "thread2 sell ticket: " << tickets-- << std::endl; } else break; SetEvent(g_hEvent); //再设置为有信号状态 } return 0; }
临界区:
#include <Windows.h> #include <iostream> DWORD WINAPI Func1Pro(LPVOID lpParameter); DWORD WINAPI Func2Pro(LPVOID lpParameter); int tickets = 100; CRITICAL_SECTION g_cs; void main() { HANDLE hThread1; HANDLE hThread2; hThread1 = CreateThread(NULL, 0, Func1Pro, NULL, 0, NULL); hThread2 = CreateThread(NULL, 0, Func2Pro, NULL, 0, NULL); CloseHandle(hThread1); CloseHandle(hThread2); InitializeCriticalSection(&g_cs); //初始化临界区对象 Sleep(4000); DeleteCriticalSection(&g_cs); } DWORD WINAPI Func1Pro(LPVOID lpParameter) { while(TRUE) { EnterCriticalSection(&g_cs); //检查是否能进入临界区 if(tickets > 0) { Sleep(1); std::cout << "thread1 sell ticket: " << tickets-- << std::endl; } else break; LeaveCriticalSection(&g_cs); } return 0; } DWORD WINAPI Func2Pro(LPVOID lpParameter) { while(TRUE) { EnterCriticalSection(&g_cs); if(tickets > 0) { Sleep(1); std::cout << "thread2 sell ticket: " << tickets-- << std::endl; } else break; LeaveCriticalSection(&g_cs); } return 0; }