多线程(7)多线程同步之互斥量(windows实现)
1. 互斥量定义
- 互斥量用来确保一个线程独占一个资源的访问。
- 互斥量是一个内核对象。
- 互斥量与临界区非常相似,并且互斥量可以用于不同进程中的线程互斥访问。
2. mutex接口概述(Windows)
2.1 CreateMutex()
2.1.1 功能:
创建一个互斥量资源对象
2.1.2 原型:
HANDLE CreateMutex(LPSECUTIRY_ATTRIBUTES lpMutexAttributes,//安全控制,一般传入NULL
BOOL bInitialOwner,//拥有者
LPCTSTR pName)//名称
2.1.3. 返回值:
成功则返回互斥量的句柄,失败返回NULL。
2.2 WaitForSingleObject()
2.2.1 功能:
- 检测hHandle事件的信号状态,在某一线程中调用该函数时,线程暂时挂起;
- 如果在挂起的dwMilliseconds毫秒内,线程所等待的对象变为有信号状态,则该函数立即返回;
- 如果超时时间已经到达dwMilliseconds毫秒,但hHandle所指向的对象还没有变成有信号状态,函数照样返回。
2.2.2. 原型:
DWORD WINAPI WaitForSingleObject(
HANDLE hHandle, // 句柄
DWORD dwMilliseconds // 时间间隔
);
hHandle对象句柄。可以指定一系列的对象,
如Event、Job、Memory resource notification、Mutex、Process、Semaphore、Thread、Waitable timer等。
2.2.3 dwMilliseconds 参数说明
参数dwMilliseconds有两个具有特殊意义的值:0和INFINITE。
若为0,则该函数立即返回;
若为INFINITE,则线程一直被挂起,直到hHandle所指向的对象变为有信号状态时为止。
2.2.4. 返回值
- WAIT_OBJECT_0 0x00000000 :指定的对象出有有信号状态
- WAIT_TIMEOUT 0x00000102: 等待超时
- WAIT_FAILED 0xFFFFFFFF :出现错误,可通过GetLastError得到错误代码
2.2.5. 优点:
这个函数的优点是它们在等待的过程中会进入一个非常高效沉睡状态,只占用极少的CPU时间片。
2.3 ReleaseMutex
2.3.1 功能:
释放互斥量
2.3.2 函数原型:
BOOL ReleaseMutex (HANDLEhMutex)
2.3.3 函数说明:
访问互斥资源前应该要调用等待函数,结束访问时就要调用ReleaseMutex()来表示自己已经结束访问,其它线程可以开始访问了。
2.4 CloseHandle
销毁句柄
5.代码例子
DWORD WINAPI mutexThreadOne(LPVOID lp)
{
while (1)
{
WaitForSingleObject(g_mutex,INFINITE);
if(g_num>0)
{
cout<<"mutexthread one sell "<<g_num<<endl;
g_num--;
ReleaseMutex(g_mutex);
}
else
{
ReleaseMutex(g_mutex);
break;
}
}
return 0;
}
DWORD WINAPI mutexThreadTwo(LPVOID lp)
{
while (1)
{
WaitForSingleObject(g_mutex,INFINITE);
if(g_num>0)
{
cout<<"mutexthread two sell "<<g_num<<endl;
g_num--;
ReleaseMutex(g_mutex);
}else{
ReleaseMutex(g_mutex);
break;
}
}
return 0;
}
void testMutex()
{
g_mutex=CreateMutex(NULL,FALSE,0);
if (!g_mutex)
{
cout<<"create mutex failed"<<endl;
return;
}
HANDLE hOne;
HANDLE hTwo;
hOne=CreateThread(0,0,mutexThreadOne,0,0,0);
hTwo=CreateThread(0,0,mutexThreadTwo,0,0,0);
WaitForSingleObject(hOne,INFINITE);
WaitForSingleObject(hTwo,INFINITE);
CloseHandle(hOne);
CloseHandle(hTwo);
//千万别忘了删除互斥量
CloseHandle(g_mutex);
}
6. 参考
https://blog.youkuaiyun.com/zhanghuaichao/article/details/53444582