多线程metex互斥量与lock_guard

//保护共享数据,防止多线程误操作,删除数据
//原则:对共享数据对象使用互斥锁(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;

}

猜你喜欢

转载自blog.csdn.net/guanxunmeng8928/article/details/107955495
今日推荐