06C++11多线程编程之lock_guard类模板
1 lock_guard概念
- 1)lock_guard是一个类模板,它是mutex的进化版,自动lock()和unlock。类似独占型智能指针unique_ptr,是一个保姆。在lock_guard生命周期结束自动释放锁,智能指针自动释放new出来的内存。
-
2)使用lock_guard后不能再使用lock和unlock,否则会出现程序不稳定甚至崩溃。
下面写一段lock_guard的伪代码:
#include <iostream>
#include <mutex>
using namespace std;
int main(){
std::mutex mymutex;
{
std::lock_guard<mutex> lGuard(mymutex);//构造时自动上锁,出去花括号后lGuard生命周期结束,锁在析构自动释放,这就是lock_guard。
}
//接下来为非共享代码,因为上面已经被释放锁
return 0;
}
2 lock_guard的共享代码案例
上一篇我们说到使用mutex的lock和unlock正确的保护了共享代码,下面我们将其替换为lock_guard。
#include<iostream>
#include<thread>
#include<string>
#include<vector>
#include<list>
#include<mutex>
using namespace std;
//准备用成员函数作为线程函数的方法写线程,成为消息处理类
class A{
public:
//把收到的消息入到一个队列的线程
void inMsgRecvQueue(){
for (int i = 0; i < 10000; i++){
cout << "inMsgRecvQueue()执行,插入一个元素" << i << endl;
{
lock_guard<mutex> lGuard(my_mutex);
//my_mutex.lock();
msgRecvQueue.push_back(i); //存放消息
//my_mutex.unlock();
}
}
}
//将共享的代码放到一个函数处理,方便上锁解锁
bool outMsgLULProc(int &command){
lock_guard<mutex> lGuard(my_mutex);
//my_mutex.lock();
if (!msgRecvQueue.empty()){
int command = msgRecvQueue.front();
msgRecvQueue.pop_front();
//my_mutex.unlock(); //所有分支都必须有unlock()
return true;
}
//my_mutex.unlock();
return false;
}
//把数据从消息队列取出的线程
void outMsgRecvQueue(){
int command = 0;
for (int i = 0; i < 10000; i++){
bool result = outMsgLULProc(command);
if (result == true){
cout << "outMsgRecvQueue()执行,取出一个元素" << endl;
//处理数据
//这里有可能也有需要共享的代码段
}
else{
//消息队列为空
cout << "inMsgRecvQueue()执行,但目前消息队列中为空!" << i << endl;
}
}
cout << "end!" << endl;
}
private:
std::list<int> msgRecvQueue;//容器(消息队列),代表玩家发送过来的命令。
std::mutex my_mutex;
};
int main(){
A myobja;
std::thread myOutMsgObj(&A::outMsgRecvQueue, &myobja);//第二个参数,地址,才能保证线程里用的是同一个对象
std::thread myInMsgObj(&A::inMsgRecvQueue, &myobja);
myOutMsgObj.join();
myInMsgObj.join();
cout << "主线程执行!" << endl;
return 0;
}
结果可以看到是正常运行的。
3 lock_guard的参数2std::adopt_lock
- 1)lock_guard的参数2只有一个std::adopt_lock。
- 2)std::adopt_lock是个结构体对象,起一个标志作用,表示这个互斥量已经lock(),不需要在std::lock_guard构造里再次lock()。
代码案例看我的下一篇死锁文章,里面详细说了std::lock配合lock_guard的参数2解决死锁并且自动解锁的案例。
版权声明:本文为weixin_44517656原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。