互斥对象(mutex)属于内核对象,它能够确保线程拥有对单个资源的互斥访问权。互斥对象包含一个使用数量,一个线程ID
和一个计数器。在这一节我们会用到三个函数,HANDLE
WINAPI
CreateMutexW(
_In_opt_ LPSECURITY_ATTRIBUTES lpMutexAttributes,
_In_ BOOL bInitialOwner,
_In_opt_ LPCWSTR lpName
);
lpMutexAttributes
BOOL
WINAPI
ReleaseMutex(
_In_ HANDLE hMutex
);
hMutex
#include
#include
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;
//创建互斥对象
hMutex = CreateMutex(NULL,true,NULL);
////计数器增加1,互斥对象内部计数器值为2
//WaitForSingleObject(hMutex, INFINITE);
//创建线程
hThread1 = CreateThread(NULL, 0, Fun1Proc, NULL, 0, NULL);
hThread2 = CreateThread(NULL, 0, Fun2Proc, NULL, 0, NULL);
//关闭句柄,函数并没有终止新创建的线程,只是表示在主线程中对新创建的线程的引用不感兴趣,因此将它关闭
CloseHandle(hThread1);
CloseHandle(hThread2);
ReleaseMutex(hMutex);
//main 函数主线程等待4秒
Sleep(4000);
system("pause");
return;
}
//线程1的入口函数
DWORD WINAPI Fun1Proc(LPVOID lpParameter){
while (true)
{
//所请求的对象属于处于有信号状态,该函数才会返回,线程才能继续往下执行
WaitForSingleObject(hMutex, INFINITE);
if (tickets > 0)
cout << "thread1 sell ticket" << tickets-- << endl;
else
break;
//释放当前线程对互斥对象的所有权,让该对象处于已通知状态
ReleaseMutex(hMutex);
}
return 0;
}
DWORD WINAPI Fun2Proc(LPVOID lpParameter){
while (true)
{
//所请求的对象属于处于有信号状态,该函数才会返回,线程才能继续往下执行,注意调用WaitForSingleObject()的位置
WaitForSingleObject(hMutex, INFINITE);
if (tickets > 0)
cout << "thread2 sell ticket" << tickets-- << endl;
else
break;
//释放当前线程对互斥对象的所有权,让该对象处于已通知状态,注意调用WaitForSingleObject()的位置
ReleaseMutex(hMutex);
}
return 0;
}