unique_lock详解
unique_lock可以取代lock_guard。
#include<thread>
#include<iostream>
#include<list>
#include<mutex>using namespace std;class A
{
public://把收到的消息(玩家命令)入到一个队列的线程void inMsgRecvQueue(){for (int i = 0; i < 100; ++i){cout << "inMsgRecvQueue()执行,插入一个元素" << i << endl;std::unique_lock<std::mutex> sbguard1(my_mutex);msgRecvQueue.push_back(i); //假设这个数字就是收到的命令,直接放到消息队列里来//.....//其他处理代码}return;}bool outMsgLULProc(int& command){std::unique_lock<std::mutex> sbguard1(my_mutex);if (!msgRecvQueue.empty()){//消息不为空 command = msgRecvQueue.front(); //返回第一个元素,但不检查元素是否存在;msgRecvQueue.pop_front(); //移除第一个元素,但不返回;return true;}return false;}//把数据从消息队列中取出的线程void outMsgRecvQueue(){int command = 0;for (int i = 0; i < 100; ++i){bool result = outMsgLULProc(command);if (result == true){cout << "outMsgRecvQueue()执行了,从容器中取出一个元素" << command << endl;//可以考虑进行命令(数据)处理//....}else{//消息对列为空cout << "outMsgRecvQueue()执行了,但目前收消息队列中是空元素" << i << endl;}}cout << "end" << endl;}
private:std::list<int> msgRecvQueue; //容器(收消息队列),专门用于代表玩家给咱们发送过来的命令std::mutex my_mutex; //创建互斥量
};int main()
{{A myobja;std::thread myOutnMsgObj(&A::outMsgRecvQueue, &myobja); //注意这里第二个参数必须是引用(用std::ref也可以),才能保证线程里用的是同一个对象std::thread myInMsgObj(&A::inMsgRecvQueue, &myobja);myInMsgObj.join();myOutnMsgObj.join();cout << "main主函数执行结束!" << endl;}return 0;
}
unique_lock的第二个参数
1、std::adopt_lock
使用std::adopt_lock的前提是开发者需要先把互斥量lock上。
#include<thread>
#include<iostream>
#include<list>
#include<mutex>using namespace std;class A
{
public://把收到的消息(玩家命令)入到一个队列的线程void inMsgRecvQueue(){for (int i = 0; i < 100; ++i){cout << "inMsgRecvQueue()执行,插入一个元素" << i << endl;my_mutex.lock();std::unique_lock<std::mutex> sbguard1(my_mutex, std::adopt_lock);msgRecvQueue.push_back(i); //假设这个数字就是收到的命令,直接放到消息队列里来//.....//其他处理代码}return;}bool outMsgLULProc(int& command){my_mutex.lock();std::unique_lock<std::mutex> sbguard1(my_mutex, std::adopt_lock);if (!msgRecvQueue.empty()){//消息不为空 command = msgRecvQueue.front(); //返回第一个元素,但不检查元素是否存在;msgRecvQueue.pop_front(); //移除第一个元素,但不返回;return true;}return false;}//把数据从消息队列中取出的线程void outMsgRecvQueue(){int command = 0;for (int i = 0; i < 100; ++i){bool result = outMsgLULProc(command);if (result == true){cout << "outMsgRecvQueue()执行了,从容器中取出一个元素" << command << endl;//可以考虑进行命令(数据)处理//....}else{//消息对列为空cout << "outMsgRecvQueue()执行了,但目前收消息队列中是空元素" << i << endl;}}cout << "end" << endl;}
private:std::list<int> msgRecvQueue; //容器(收消息队列),专门用于代表玩家给咱们发送过来的命令std::mutex my_mutex; //创建互斥量
};int main()
{{A myobja;std::thread myOutnMsgObj(&A::outMsgRecvQueue, &myobja); //注意这里第二个参数必须是引用(用std::ref也可以),才能保证线程里用的是同一个对象std::thread myInMsgObj(&A::inMsgRecvQueue, &myobja);myInMsgObj.join();myOutnMsgObj.join();cout << "main主函数执行结束!" << endl;}return 0;
}
2、std::try_to_lock
使用std::try_to_lock的前提是开发者不可以自己把互斥量lock上。
#include<thread>
#include<iostream>
#include<list>
#include<mutex>using namespace std;class A
{
public://把收到的消息(玩家命令)入到一个队列的线程void inMsgRecvQueue(){for (int i = 0; i < 100; ++i){cout << "inMsgRecvQueue()执行,插入一个元素" << i << endl;//std::unique_lock<std::mutex> sbguard1(my_mutex, std::adopt_lock);//std::unique_lock<std::mutex> sbguard1(my_mutex);std::unique_lock<std::mutex> sbguard1(my_mutex, std::try_to_lock);if (sbguard1.owns_lock()) //条件成立表示拿到了锁头{//拿到了锁头,离开sbguard1作用域锁头会自动释放msgRecvQueue.push_back(i); //假设这个数字就是收到的命令,直接放到消息队列里来//.....//其他处理代码}else{//没拿到锁cout << "inMsgRecvQueue()执行,但没拿到锁,只能干点别的事" << i << endl;}}}bool outMsgLULProc(int& command){std::unique_lock<std::mutex> sbguard1(my_mutex);std::chrono::milliseconds dura(20000); //定义一个时间相关对象,初值2万,单位毫秒, 卡在这里20秒std::this_thread::sleep_for(dura);if (!msgRecvQueue.empty()){//消息不为空 command = msgRecvQueue.front(); //返回第一个元素,但不检查元素是否存在;msgRecvQueue.pop_front(); //移除第一个元素,但不返回;return true;}return false;}//把数据从消息队列中取出的线程void outMsgRecvQueue(){int command = 0;for (int i = 0; i < 100000; ++i){bool result = outMsgLULProc(command);if (result == true){cout << "outMsgRecvQueue()执行了,从容器中取出一个元素" << command << endl;//可以考虑进行命令(数据)处理//....}else{//消息对列为空cout << "outMsgRecvQueue()执行了,但目前收消息队列中是空元素" << i << endl;}}cout << "end" << endl;}
private:std::list<int> msgRecvQueue; //容器(收消息队列),专门用于代表玩家给咱们发送过来的命令std::mutex my_mutex; //创建互斥量std::mutex my_mutex2; //创建互斥量
};int main()
{{A myobja;std::thread myOutnMsgObj(&A::outMsgRecvQueue, &myobja); //注意这里第二个参数必须是引用(用std::ref也可以),才能保证线程里用的是同一个对象std::thread myInMsgObj(&A::inMsgRecvQueue, &myobja);myInMsgObj.join();myOutnMsgObj.join();cout << "main主函数执行结束!" << endl;}return 0;
}
3、std::defer_lock
使用defer_lock的前提是开发者不能自己吧互斥量lock上,否则会报异常
unique_lock的成员函数
1、lock
给互斥量加锁,如果无法拿到锁,会阻塞一直等待拿到锁。
//把收到的消息(玩家命令)入到一个队列的线程void inMsgRecvQueue(){for (int i = 0; i < 100000; ++i){cout << "inMsgRecvQueue()执行,插入一个元素" << i << endl;std::unique_lock<std::mutex> sbguard1(my_mutex, std::defer_lock);sbguard1.lock(); //反正unique_lock能自动解锁,不用自己解,所以这里只管加锁msgRecvQueue.push_back(i);}}
2、unlock
针对加锁的互斥量,给该互斥量解锁,不可以针对没加锁的互斥量使用,否则会报异常。
3、try_lock
尝试给互斥量加锁,如果拿不到锁,则返回false;如果拿到了锁,则返回true。这个成员函数不阻塞。
//把收到的消息(玩家命令)入到一个队列的线程void inMsgRecvQueue(){for (int i = 0; i < 100000; ++i){cout << "inMsgRecvQueue()执行,插入一个元素" << i << endl;std::unique_lock<std::mutex> sbguard1(my_mutex, std::defer_lock);if (sbguard1.try_lock() == true) //返回true表示拿到了锁,自己不用管unlock问题{msgRecvQueue.push_back(i);}else{cout << "抱歉,没拿到锁,做点别的事情吧!" << endl;}}}
4、release
//把收到的消息(玩家命令)入到一个队列的线程void inMsgRecvQueue(){for (int i = 0; i < 100000; ++i){cout << "inMsgRecvQueue()执行,插入一个元素" << i << endl;std::unique_lock<std::mutex> sbguard1(my_mutex); //mutex锁定std::mutex* p_mtx = sbguard1.release(); //现在关联关系解除,程序员有责任自己解锁了,其实这个就是my_mutex,现在sbguard1已经不和my_mutex关联了(可以设置断点并观察)msgRecvQueue.push_back(i);p_mtx->unlock();//因为前面已经加锁,所以这里要自己解锁了 }return;}
unique_lock详解相关推荐
- 17.6 unique_lock详解
一.unique_lock取代lock_guard unique_lock 是个类模板,工作中,一般 lock_guard(推荐使用),lock_guard取代了 mutex 的 lock() 和 u ...
- unique_lock 详解
(1) unique_lock 取代lock_guard (2)unique_lock的第二个参数 2.1.std::adopt_lock 2.2 std::try_to_lock 2.3 std:: ...
- ORB-SLAM2代码/流程详解
ORB-SLAM2代码详解 文章目录 ORB-SLAM2代码详解 1. ORB-SLAM2代码详解01_ORB-SLAM2代码运行流程 1 运行官方Demo 1.2. 阅读代码之前你应该知道的事情 1 ...
- C++条件变量使用详解
1. condition_variable介绍 在C++11中,我们可以使用条件变量(condition_variable)实现多个线程间的同步操作:当条件不满足时,相关线程被一直阻塞,直到某种条件出 ...
- C++11 并发指南三(std::mutex 详解)
上一篇<C++11 并发指南二(std::thread 详解)>中主要讲到了 std::thread 的一些用法,并给出了两个小例子,本文将介绍 std::mutex 的用法. Mutex ...
- 【转】C++11 并发指南五(std::condition_variable 详解)
http://www.cnblogs.com/haippy/p/3252041.html 前面三讲<C++11 并发指南二(std::thread 详解)>,<C++11 并发指南三 ...
- C++11 并发指南五(std::condition_variable 详解)
前面三讲<C++11 并发指南二(std::thread 详解)>,<C++11 并发指南三(std::mutex 详解)>分别介绍了 std::thread,std::mut ...
- C++11 并发指南三(Lock 详解)
在 <C++11 并发指南三(std::mutex 详解)>一文中我们主要介绍了 C++11 标准中的互斥量(Mutex),并简单介绍了一下两种锁类型.本节将详细介绍一下 C++11 标准 ...
- C++11 并发指南三(Lock 详解)(转载)
multithreading 多线程 C++11 C++11多线程基本使用 C++11 并发指南三(Lock 详解) 在 <C++11 并发指南三(std::mutex 详解)>一文中我们 ...
最新文章
- THINKPHP 分页类
- 笔记本电脑下载python视频教程-Python的Jupyter Notebook入门教程
- python中plot柱状图-python matplotlib模块: bar(柱状图)
- python if语句多个条件-Python 条件语句(if..elif..else)
- ThinkPHP 目录结构
- 感知器的c++实现_使用FastAI和PyTorch的多层感知器
- eclipse 安装svn插件 及试用
- ios 返回不会自动刷新页面问题
- Python的DEBUG LOG
- 第一次作业:深入Linux源码分析进程模型
- mysql c函数大全_Mysql 函数大全
- python导入模块_Python导入
- ORB_SLAM2探秘 第三章 LoopClosing线程
- DM9000驱动之接受
- k2p华硕系统怎么设置_斐讯k2华硕固件,斐讯k2p华硕固件设置
- 江苏自考计算机专业,2021年江苏自考本科专业选择:计算机类专业前景如何?有哪些科目?...
- 【理解】运用数据透视表制作三栏账
- Unity 中 print 和 Debug.Log 的区别
- 黑镜第一至二季/全集Black Mirror迅雷下载
- lt19264a+c语言程序,可以直接显示汉字的19264液晶驱动C语言程序