//一.unique_lock取代lock_guard
//unique_lock 是个类模板,工作中,一般lock_guard(推荐使用);lock_guard 取代了lock()和unlock()
//unique_lock 比lock_guard 灵活很多;效率上差一点,内存占用多一点。
//二.unique_lock的第二个参数:
//2.1:std::adopt_lock:起标记作用,表示这个互斥量已经被lock了(所以必去把互斥量提前lock了,否则会报异常)
//2.2:std::try_to_lock:尝试锁定mutex,如果没有成功,就会立即返回,不会阻塞函数进程。(配合if...else)
//使用try_to_lock前提,函数中不能先去lock
//2.3:std::defer_lock:初始化了一个没有加锁的mutex
//三.unique_lock的成员函数(使用了defer_lock才能使用成员函数)
//3.1:lock()加锁
//3.2:unlock()解锁,
//3.3:try_lock() 拿到锁返回true,没有返回unlock
//3.4:release(),返回它所管理的mutext对象指针,并释放所有权,也就是说,unique_lock和mutext不再有关系
//3.5:为什么要用unlock:lock住的代码越少,执行越快,整个程序运行效率越高
/*
锁住的代码行数,称为锁的粒度。
锁住的代码少,粒度细,执行效率高,
锁住的代码多,粒度粗,执行效率低。
粒度太细,可能漏掉共享数据的保护,粒度太粗,影响效率。
*/
//四:unique_lock所有权的传递mutex,
/*
std::unique_lock<std::mutex>uqName(mutex_name);//所有权概念
uqName拥有mutex_name的所有权
uqName可以把对于mutex_name的所有权转移给其他unique_lock对象。std::move
所以unique_lock的所有权可以转移但是不可复制
*/
//4.0:std::move
//4.1:
/*std::unique_lock<mutex>return_uqLock()
{
unique_lock<mutex>tmp_lock(my_mutex2);
return tmp_lock;
}*/
#include<iostream>
#include<thread>
#include<vector>//适合乱序取出数据
#include<list>//适合有序取出数据
#include<mutex>//互斥量
using namespace std;
class A {
public:
//4.1return lock转移所有权
std::unique_lock<mutex>return_uqLock()
{
unique_lock<mutex>tmp_lock(my_mutex2);
return tmp_lock;
}
void inMsgRecvQueue()
{
for (int i = 0; i < 10000; i++)
{
cout << "Insert a number in inMsgRecvQueue():" << i << endl;
//unique_lock 模式
unique_lock<mutex>msgRecGuard2(my_mutex2);
//sleep 2 second
std::chrono::milliseconds waitTime(2000);
std::this_thread::sleep_for(waitTime);
//2.1:adopt_lock
/*
my_mutex.lock();
std::unique_lock<std::mutex>msgRecGuard(my_mutex,adopt_lock);
*/
msgRecvQueue.push_back(i);
}
}
void outMsgRecvQueue()
{
int command = 0;
for (int i = 0; i < 10000; i++)
{
//2.2
/*unique_lock<mutex>getNum2(my_mutex2, try_to_lock);
//if (getNum2.owns_lock()) {*/
//unique_lock<mutex>getNum2(my_mutex2, defer_lock);//没有加锁的my_mutex2,创在一个指针getNum2指向my_mutex2
//getNum2.lock();//getNum2上锁,my_mutex2加锁,getNum2会自动解锁,所以不用unlock
//...
//3.2
/*getNum2.unlock();
处理一些非共享代码....
处理结束.
//接着上锁处理共享代码
getNum2.lock();
*/
//-------------
//3.3:try_lock
//if(getNum2.try_lock()==true){}//返回true表示拿到锁了
//-------------
//3.4:release
/*
std::unique_lock<mutex>getNum2(my_mutex2);
std::mutex *ptx=getNum2.release();//getNum2与my_mutex2解除关系,ptx与mutex2绑定
//所以下面需要对mutex2进行手动解锁。
*/
//4.0转移所有权
//std::unique_lock<mutex>getNum2(my_mutex2);
//std::unique_lock<mutex>getNum3(std::move(getNum2));//Num2对于mutex2的所有权转移给Num3
//4.1给return赋值
unique_lock<mutex>getReNum = return_uqLock();
//封装判断
bool result = getTheNumber(command);
if (result == true)
{
cout << "outMsg running, get the number:" << command << endl;;
//处理进行处理command数据
//...
}
else
{
cout << "outMsg is running,but the list is empty!" << endl;;
}
//}
//2.2
/*else
{
cout << "GetNum didn't get the lock" << ".We will do sth else." << endl;
}*/
//3.4:手动解锁
//ptx->unlock();
}
}
private:
list<int>msgRecvQueue;
mutex my_mutex;//我的互斥量
mutex my_mutex2;//测试死锁
protected:
bool getTheNumber(int& command)//取command地址,所以修改了command的数据
{
//unique_lock<mutex>getNum2(my_mutex2);
if (!msgRecvQueue.empty())
{
command = msgRecvQueue.front();//Return the first value of the msgRecvQueue,but front doesn't check data
msgRecvQueue.pop_front();//Delete the first number of the msgRQ
return true;
}
return false;
}
};
int main() {
A myobj;
thread myOutMsgObj(&A::outMsgRecvQueue, &myobj);
thread myInMsgObj(&A::inMsgRecvQueue, &myobj);
if(myInMsgObj.joinable())
myInMsgObj.join();
else
cout << "The myInMsg is joined!" << endl;
if (myOutMsgObj.joinable())
myOutMsgObj.join();
else
cout << "The myOutMsg is joined!" << endl;
}
unique_lock
猜你喜欢
转载自blog.csdn.net/guanxunmeng8928/article/details/108034529
今日推荐
周排行