//保护共享数据,防止多线程误操作,删除数据
//原则:对共享数据对象使用互斥锁(mutex),锁定数据,只让一方操作数据,坚持读写分离(只写不读,只读不写)
//lock 和 unlock 要成对使用
//锁定的代码越少执行的越快,所以可以剥离一些模块成为函数,直接锁定这个函数
//防止大家忘记添加unlock(),引入了一个std::lock_guard的类模板:你忘记unlock,它替你unlock
//lock_guard直接取代了lock()和unlock()。使用了lock_guard ,就不能使用lock和unlock
//智能指针(unique_ptr):你忘记释放内存,我给你释放;
#include<iostream>
#include<thread>
#include<vector>//适合乱序取出数据
#include<list>//适合有序取出数据
#include<mutex>//互斥量
using namespace std;
class A {
public:
void inMsgRecvQueue()
{
for (int i = 0; i < 10000; i++)
{
cout << "Insert a number in inMsgRecvQueue():" << i << endl;
//my_mutex.lock();
//使用{}作用域强行让lock_guard 析构
{
lock_guard<std::mutex>InMsgGuard(my_mutex);
msgRecvQueue.push_back(i);
//析构
}
//my_mutex.unlock();
}
}
void outMsgRecvQueue()
{
int command = 0;
for (int i = 0; i < 10000; i++)
{
//封装判断
bool result = getTheNumber(command);
if (result == true)
{
cout << "outMsg running, get the number:" << command ;
//处理进行处理command数据
//...
}
else {
cout << "outMsg is running,but the list is empty!";
}
cout << endl;
//不封装判断
//The msg is not empty
/*if (!msgRecvQueue.empty())
{
int command = msgRecvQueue.front();//Return the first value of the msgRecvQueue,but front doesn't check data
cout << "Get the number from outMsgRQ: " << command;
msgRecvQueue.pop_front();//Delete the first number of the msgRQ
}
else
{
cout << "outMsg is running,but the list is empty!" ;
}
cout << endl;*/
}
}
private:
list<int>msgRecvQueue;
mutex my_mutex;//我的互斥量
protected:
bool getTheNumber(int &command)//取command地址,所以修改了command的数据
{
lock_guard<std::mutex>outmsgGuard(my_mutex);//删除所有lock与unlock,灵活性差
//lock_guard构造函数里执行了 mutex.lock()
//my_mutex.lock();
//两个unlock,因为程序if 给创造了两个分支
if (!msgRecvQueue.empty())
{
//int command //那么&command 就失效了,下列的command就会处理这个局部的command。
command = msgRecvQueue.front();//Return the first value of the msgRecvQueue,but front doesn't check data
//cout << "Get the number from outMsgRQ: " << command;
msgRecvQueue.pop_front();//Delete the first number of the msgRQ
//lock_guard作为局部对象,在退出函数的时候需要析构,在他的析构函数里调用mutex.unlock
//my_mutex.unlock();
return true;
}
//my_mutex.unlock();
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;
}
多线程metex互斥量与lock_guard
最新推荐文章于 2023-09-18 13:28:53 发布