目录
一、前言
本文接上文 【学习笔记】C++并发与多线程笔记四:互斥量(概念、用法、死锁) 的内容,主要纪录 unique_lock
的使用方法以及原理。
二、uniqie_lock取代lock_quard
uniqie_lock 是个类模板,它的功能跟 lock_quard 类似,但比 lock_quard 更灵活。在工作中,一般用 lock_quard (推荐使用)就足够了,但在一些特殊的场景下会用到 uniqie_lock。
在上篇文章中讲到了 lock_quard 取代了 mutex 的 lock() 和 unlock(),在 lock_quard 的构造函数中上锁,在析构函数中解锁,这点其实在 uniqie_lock 中也是一样的。
uniqie_lock 在使用上比 lock_quard 灵活,但代价就是效率会低一点,并且内存占用量也会相对高一些。
uniqie_lock 的缺省用法实际上与 lock_quard 一样,可以直接替换,代码如下:
#include <iostream>
#include <thread>
#include <mutex>
#include <list>
using namespace std;
class A {
public:
/* 把收到的消息(玩家命令)存到队列中 */
void inMsgRecvQueue() {
for (int i = 0; i < 100000; ++i) {
cout << "inMsgRecvQueue exec, push an elem " << i << endl;
std::unique_lock<std::mutex> m_guard1(m_mutex1);
msgRecvQueue.push_back(i); /* 假设数字 i 就是收到的玩家命令 */
}
}
/* 消息队列不为空时,返回并弹出第一个元素 */
bool outMsgLULProc(int& command) {
std::unique_lock<std::mutex> m_guard1(m_mutex1);
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)
cout << "outMsgLULProc exec, and pop_front: " << command << endl;
else
cout << "outMsgRecvQueue exec, but queue is empty!" << i << endl;
cout