首选使用临界区对象,主要原因是使用简单。
#include <iostream> using namespace std; DWORD WINAPI Fun1Proc(LPVOID lpParameter); DWORD WINAPI Fun2Proc(LPVOID lpParameter); int tickets=100; CRITICAL_SECTION g_csA; CRITICAL_SECTION g_csB; void main() { HANDLE hThread1; HANDLE hThread2; hThread1=CreateThread(NULL,0,Fun1Proc,NULL,0,NULL); hThread2=CreateThread(NULL,0,Fun2Proc,NULL,0,NULL); CloseHandle(hThread1); CloseHandle(hThread2); InitializeCriticalSection(&g_csA); InitializeCriticalSection(&g_csB); Sleep(40000); DeleteCriticalSection(&g_csA); DeleteCriticalSection(&g_csB); } DWORD WINAPI Fun1Proc(LPVOID lpParameter) { while (TRUE) { EnterCriticalSection(&g_csA); Sleep(1); //EnterCriticalSection(&g_csB);//临界区的同步和互锁 if (tickets>0) { Sleep(1); cout<<"Thread1 sell ticket :"<<tickets--<<endl; //LeaveCriticalSection(&g_csB); LeaveCriticalSection(&g_csA); } else { //LeaveCriticalSection(&g_csB); LeaveCriticalSection(&g_csA); break; } } return 0; } DWORD WINAPI Fun2Proc(LPVOID lpParameter) { while (TRUE) { EnterCriticalSection(&g_csB); Sleep(1); EnterCriticalSection(&g_csA); if (tickets>0) { Sleep(1); cout<<"Thread2 sell ticket :"<<tickets--<<endl; LeaveCriticalSection(&g_csA); LeaveCriticalSection(&g_csB); } else { LeaveCriticalSection(&g_csA); LeaveCriticalSection(&g_csB); break; } } return 0; }
二、使用互斥对象 #include <windows.h> #include <iostream> using namespace std; DWORD WINAPI Fun1Proc(LPVOID lpParameter); DWORD WINAPI Fun2Proc(LPVOID lpParameter); int index =0; int tickets=100; HANDLE hMutex; void main() { HANDLE hThread1; HANDLE hThread2; //创建线程 hThread1=CreateThread(NULL,0,Fun1Proc,NULL,0,NULL); hThread2=CreateThread(NULL,0,Fun2Proc,NULL,0,NULL); CloseHandle(hThread1); CloseHandle(hThread2); //************************************************************** //保证应用程序只有一个实例运行,创建一个命名的互斥对象. hMutex=CreateMutex(NULL,TRUE,LPCTSTR("tickets")); //创建时主线程拥有该互斥对象,互斥对象的线程ID为主线程的ID,同时将该互斥对象内部计数器置为1 if (hMutex) { if (ERROR_ALREADY_EXISTS==GetLastError()) { cout<<"only one instance can run!"<<endl; //Sleep(40000); return; } } //************************************************************** WaitForSingleObject(hMutex,INFINITE); //使用该函数请求互斥对象时,虽说该对象处于无信号状态,但因为请求的线程ID和该互斥对象所有者的线程ID是相同的.所以仍然可以请求到这个互斥对象,于是该互斥对象内部计数器加1,内部计数器的值为2. 意思是有两个等待动作 ReleaseMutex(hMutex);//释放一次互斥对象,该互斥对象内部计数器的值递减1,操作系统不会将这个互斥对象变为已通知状态. ReleaseMutex(hMutex);//释放一次互斥对象,该互斥对象内部计数器的值为0,同时将该对象设置为已通知状态. //对于互斥对象来说,谁拥有谁释放 Sleep(40000); } DWORD WINAPI Fun1Proc(LPVOID lpParameter) { while (TRUE) { WaitForSingleObject(hMutex,INFINITE);//等待互斥对象有信号 if (tickets>0) { Sleep(1); cout<<"thread1 sell ticket :"<<tickets--<<endl; } else break; ReleaseMutex(hMutex);//设置该互斥对象的线程ID为0,并且将该对象设置为有信号状态 } return 0; } DWORD WINAPI Fun2Proc(LPVOID lpParameter) { while (TRUE) { WaitForSingleObject(hMutex,INFINITE); if (tickets>0) { Sleep(1); cout<<"thread2 sell ticket :"<<tickets--<<endl; } else break; ReleaseMutex(hMutex); } return 0;
三、使用事件对象 #include <windows.h> void main() Sleep(40000); DWORD WINAPI Fun1Proc(LPVOID lpParameter) DWORD WINAPI Fun2Proc(LPVOID lpParameter) |
联系客服