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详解相关推荐

  1. 17.6 unique_lock详解

    一.unique_lock取代lock_guard unique_lock 是个类模板,工作中,一般 lock_guard(推荐使用),lock_guard取代了 mutex 的 lock() 和 u ...

  2. unique_lock 详解

    (1) unique_lock 取代lock_guard (2)unique_lock的第二个参数 2.1.std::adopt_lock 2.2 std::try_to_lock 2.3 std:: ...

  3. ORB-SLAM2代码/流程详解

    ORB-SLAM2代码详解 文章目录 ORB-SLAM2代码详解 1. ORB-SLAM2代码详解01_ORB-SLAM2代码运行流程 1 运行官方Demo 1.2. 阅读代码之前你应该知道的事情 1 ...

  4. C++条件变量使用详解

    1. condition_variable介绍 在C++11中,我们可以使用条件变量(condition_variable)实现多个线程间的同步操作:当条件不满足时,相关线程被一直阻塞,直到某种条件出 ...

  5. C++11 并发指南三(std::mutex 详解)

    上一篇<C++11 并发指南二(std::thread 详解)>中主要讲到了 std::thread 的一些用法,并给出了两个小例子,本文将介绍 std::mutex 的用法. Mutex ...

  6. 【转】C++11 并发指南五(std::condition_variable 详解)

    http://www.cnblogs.com/haippy/p/3252041.html 前面三讲<C++11 并发指南二(std::thread 详解)>,<C++11 并发指南三 ...

  7. C++11 并发指南五(std::condition_variable 详解)

    前面三讲<C++11 并发指南二(std::thread 详解)>,<C++11 并发指南三(std::mutex 详解)>分别介绍了 std::thread,std::mut ...

  8. C++11 并发指南三(Lock 详解)

    在 <C++11 并发指南三(std::mutex 详解)>一文中我们主要介绍了 C++11 标准中的互斥量(Mutex),并简单介绍了一下两种锁类型.本节将详细介绍一下 C++11 标准 ...

  9. C++11 并发指南三(Lock 详解)(转载)

    multithreading 多线程 C++11 C++11多线程基本使用 C++11 并发指南三(Lock 详解) 在 <C++11 并发指南三(std::mutex 详解)>一文中我们 ...

最新文章

  1. THINKPHP 分页类
  2. 笔记本电脑下载python视频教程-Python的Jupyter Notebook入门教程
  3. python中plot柱状图-python matplotlib模块: bar(柱状图)
  4. python if语句多个条件-Python 条件语句(if..elif..else)
  5. ThinkPHP 目录结构
  6. 感知器的c++实现_使用FastAI和PyTorch的多层感知器
  7. eclipse 安装svn插件 及试用
  8. ios 返回不会自动刷新页面问题
  9. Python的DEBUG LOG
  10. 第一次作业:深入Linux源码分析进程模型
  11. mysql c函数大全_Mysql 函数大全
  12. python导入模块_Python导入
  13. ORB_SLAM2探秘 第三章 LoopClosing线程
  14. DM9000驱动之接受
  15. k2p华硕系统怎么设置_斐讯k2华硕固件,斐讯k2p华硕固件设置
  16. 江苏自考计算机专业,2021年江苏自考本科专业选择:计算机类专业前景如何?有哪些科目?...
  17. 【理解】运用数据透视表制作三栏账
  18. Unity 中 print 和 Debug.Log 的区别
  19. 黑镜第一至二季/全集Black Mirror迅雷下载
  20. lt19264a+c语言程序,可以直接显示汉字的19264液晶驱动C语言程序

热门文章

  1. iOS开发之使用UICollectionView实现美团App的分类功能【偶现大众点评App的一个小bug】...
  2. 知识图谱在畜牧业中的应用实例
  3. 数值计算方法之数值积分与微分
  4. currentStyle与getComputedStyle应用
  5. H.266/VVC标准文本
  6. iOS runtime 详解和使用场景(最详细的使用教程)
  7. @MapperScan的使用
  8. 开机即打开Numlock
  9. c语言cum什么意思,cum是什么单位
  10. SEO优化帝国cms制作xml网站地图