1、其他线程锁及其使用
临界区:Critical_Region
在同一个线程中,windows的 "相同临界区变量" 代表的临界区的进入可以被多次调用,几次调用就需要几次释放
recursive_mutex递归独占互斥量
std::lock_guard<std::recursive_mutex>
std::time_mutex:带超时功能的独占互斥量
// try_lock_for() 等待一段时间,如果超时没拿到锁,或者已经拿到锁了,流程就往下走
// try_lock_unit()
std::recursive_time_mutex:带超时功能的独占互斥量
首先介绍临界锁的使用
#include <iostream>
#include <thread>
#include <mutex>
#include <list>
//#include "CWinLock.hpp"
#include <windows.h>
using namespace std;
#define __WINDOWSJQ_ // 定义windows运行环境
class CriticalRegion
{
public:
CriticalRegion()
{
#ifdef __WINDOWSJQ_
InitializeCriticalSection(&m_CSCtrls);
#endif // __WINDOWSJQ_
}
~CriticalRegion()
{
#ifdef __WINDOWSJQ_
DeleteCriticalSection(&m_CSCtrls);
#endif // __WINDOWSJQ_
}
// 存数据
void inMsgRecvQueue()
{
for (int i = 0; i < 1000; i++)
{
cout << "input list i:" << i << endl;
#ifdef __WINDOWSJQ_
// CWinLock wLock(&m_CSCtrls);
EnterCriticalSection(&m_CSCtrls);
m_RecvQueue.push_back(i);
LeaveCriticalSection(&m_CSCtrls);
#else
m_Mutex.lock();
m_RecvQueue.push_back(i);
m_Mutex.unlock();
#endif
}
// doSomething
// ...
}
bool outMsgQueue(int &num)
{
#ifdef __WINDOWSJQ_
EnterCriticalSection(&m_CSCtrls);
if (!m_RecvQueue.empty())
{
num = m_RecvQueue.front(); // 返回第一个元素,但是不检查元素是否存在;
m_RecvQueue.pop_front(); // 移除第一个元素但不反回
LeaveCriticalSection(&m_CSCtrls); //m_Mutex.unlock();
return true;
}
LeaveCriticalSection(&m_CSCtrls);
#else
m_Mutex.lock();
if (!m_RecvQueue.empty())
{
num = m_RecvQueue.front(); // 返回第一个元素,但是不检查元素是否存在;
m_RecvQueue.pop_front(); // 移除第一个元素但不反回
m_Mutex.unlock(); //m_Mutex.unlock();
return true;
}
m_Mutex.unlock();
#endif // __WINDOWSJQ_
return false;
}
// 取数据
void outMsgRecvQueue()
{
EnterCriticalSection(&m_CSCtrls);
int num;
for (int i = 0; i < 1000; i++)
{
if (outMsgQueue(num))
{
cout << "delet one data" << num << endl;
}
else
{
cout << "outMsgRecvQueue no data" << endl;
}
}
cout << "end" << endl;
LeaveCriticalSection(&m_CSCtrls);
}
private:
std::list<int> m_RecvQueue;
//互斥量
std::mutex m_Mutex;
#ifdef __WINDOWSJQ_
// 临界锁,类似于互斥量
CRITICAL_SECTION m_CSCtrls;
#endif // __WINDOWSJQ__
};
int main()
{
CriticalRegion CRobj;
std::thread t1(&CriticalRegion::inMsgRecvQueue, &CRobj);
std::thread t2(&CriticalRegion::outMsgRecvQueue, &CRobj);
t1.join();
t2.join();
system("pause");
return 0;
}
也可以简化临界锁的使用,定义一个CWinLock()函数用于定于与释放临界锁
#include <windows.h>
// 用于自动释放windows下的临界区,防止忘记释放
// RAII类 资源获取即初始化
class CWinLock
{
public:
CWinLock(CRITICAL_SECTION *pCritical)
{
m_pCritical = pCritical;
EnterCriticalSection(m_pCritical);
}
~CWinLock(CRITICAL_SECTION *pCritical)
{
LeaveCriticalSection(m_pCritical);
}
private:
CRITICAL_SECTION *m_pCritical;
};