1.通过事件对象实现同步
①创建事件对象CreateEvent
②设置为激活常态SetEvent
③等待信号量WaitForSingleObject
④关闭事件句柄CloseHandle
代码:
#include <Windows.h> #include <iostream> using namespace std; int tickets = 100; HANDLE g_Event;//事件对象句柄 DWORD WINAPI OneSellTickets(LPVOID lpParam); DWORD WINAPI TwoSellTickets(LPVOID lpParam); void main() { //创建事件句柄, g_Event = CreateEvent(NULL, //安全性,默认是NULL FALSE, //FALSE表示线程释放后自动复位为无信号,TRUE要手动复位 FALSE, //TRUE表示有信号状态,FALSE表示无信号状态 TEXT("tickets")); if (g_Event) { if (ERROR_ALREADY_EXISTS == GetLastError()) { cout<<"only one instance can run"<<endl; return ; } } SetEvent(g_Event); HANDLE handleOne = CreateThread(NULL,0,OneSellTickets,NULL,0,NULL); HANDLE handleTwo = CreateThread(NULL,0,TwoSellTickets,NULL,0,NULL); CloseHandle(handleOne); CloseHandle(handleTwo); Sleep(1000); CloseHandle(g_Event); cin.get(); cin.get(); } DWORD WINAPI OneSellTickets(LPVOID lpParam) { while (TRUE) { WaitForSingleObject(g_Event,INFINITE); if (tickets > 0) { cout<<"One Sell Tickets"<<tickets--<<endl; SetEvent(g_Event); } else { SetEvent(g_Event); break; } } return 0; } DWORD WINAPI TwoSellTickets(LPVOID lpParam) { while (TRUE) { WaitForSingleObject(g_Event,INFINITE); if (tickets > 0) { cout<<"Two Sell Tickets"<<tickets-- <<endl; SetEvent(g_Event); } else { SetEvent(g_Event); break; } } return 0; }
2.临界区:
①设置临界区结构体 CRITICAL_SECTION
②初始化临界区 InitializeCriticalSection
③进入临界区 EnterCriticalSection
④离开临界区 LeaveCriticalSection
⑤销毁临界区 DeleteCriticalSection
#include <Windows.h> #include <iostream> using namespace std; int tickets = 100; CRITICAL_SECTION g_cs;//设置临界区结构体的全局变量 DWORD WINAPI OneSellTickets(LPVOID lpParam); DWORD WINAPI TwoSellTickets(LPVOID lpParam); void main() { InitializeCriticalSection(&g_cs); HANDLE handleOne = CreateThread(NULL,0,OneSellTickets,NULL,0,NULL); HANDLE handleTwo = CreateThread(NULL,0,TwoSellTickets,NULL,0,NULL); CloseHandle(handleOne); CloseHandle(handleTwo); Sleep(1000); DeleteCriticalSection(&g_cs); cin.get(); cin.get(); } DWORD WINAPI OneSellTickets(LPVOID lpParam) { while (TRUE) { EnterCriticalSection(&g_cs); if (tickets > 0) { cout<<"One Sell Tickets"<<tickets--<<endl; LeaveCriticalSection(&g_cs); } else { LeaveCriticalSection(&g_cs); break; } } return 0; } DWORD WINAPI TwoSellTickets(LPVOID lpParam) { while (TRUE) { EnterCriticalSection(&g_cs); if (tickets > 0) { cout<<"Two Sell Tickets"<<tickets-- <<endl; LeaveCriticalSection(&g_cs); } else { LeaveCriticalSection(&g_cs); break; } } return 0; }