unique_lock

//一.unique_lock取代lock_guard
//unique_lock 是个类模板,工作中,一般lock_guard(推荐使用);lock_guard 取代了lock()和unlock()
//unique_lock 比lock_guard 灵活很多;效率上差一点,内存占用多一点。
//二.unique_lock的第二个参数:
//2.1:std::adopt_lock:起标记作用,表示这个互斥量已经被lock了(所以必去把互斥量提前lock了,否则会报异常)
//2.2:std::try_to_lock:尝试锁定mutex,如果没有成功,就会立即返回,不会阻塞函数进程。(配合if...else)
//使用try_to_lock前提,函数中不能先去lock
//2.3:std::defer_lock:初始化了一个没有加锁的mutex
//三.unique_lock的成员函数(使用了defer_lock才能使用成员函数)
//3.1:lock()加锁
//3.2:unlock()解锁,
//3.3:try_lock() 拿到锁返回true,没有返回unlock
//3.4:release(),返回它所管理的mutext对象指针,并释放所有权,也就是说,unique_lock和mutext不再有关系
//3.5:为什么要用unlock:lock住的代码越少,执行越快,整个程序运行效率越高
/*
锁住的代码行数,称为锁的粒度。
锁住的代码少,粒度细,执行效率高,
锁住的代码多,粒度粗,执行效率低。
粒度太细,可能漏掉共享数据的保护,粒度太粗,影响效率。
*/
//四:unique_lock所有权的传递mutex,
/*
std::unique_lock<std::mutex>uqName(mutex_name);//所有权概念
uqName拥有mutex_name的所有权
uqName可以把对于mutex_name的所有权转移给其他unique_lock对象。std::move
所以unique_lock的所有权可以转移但是不可复制
*/
//4.0:std::move
//4.1:
	/*std::unique_lock<mutex>return_uqLock()
	{
	unique_lock<mutex>tmp_lock(my_mutex2);
	return tmp_lock;
	}*/
#include<iostream>
#include<thread>
#include<vector>//适合乱序取出数据
#include<list>//适合有序取出数据
#include<mutex>//互斥量

using namespace std;

class A {
    
    


public:
	//4.1return lock转移所有权
	std::unique_lock<mutex>return_uqLock()
	{
    
    
		unique_lock<mutex>tmp_lock(my_mutex2);
		return tmp_lock;
	}

	void inMsgRecvQueue()
	{
    
    
		for (int i = 0; i < 10000; i++)
		{
    
    
			cout << "Insert a number in inMsgRecvQueue():" << i << endl;
			
		
			//unique_lock 模式
			unique_lock<mutex>msgRecGuard2(my_mutex2);
			//sleep 2 second
			std::chrono::milliseconds waitTime(2000);
			std::this_thread::sleep_for(waitTime);
			//2.1:adopt_lock
			/*
			my_mutex.lock();
			std::unique_lock<std::mutex>msgRecGuard(my_mutex,adopt_lock);
			*/
			
			
	
			
			msgRecvQueue.push_back(i);
		}
	}
	
	
	 
void outMsgRecvQueue()
{
    
    
	int command = 0;
	
	for (int i = 0; i < 10000; i++)
	{
    
    
		//2.2		
		/*unique_lock<mutex>getNum2(my_mutex2, try_to_lock);
		//if (getNum2.owns_lock()) {*/

		//unique_lock<mutex>getNum2(my_mutex2, defer_lock);//没有加锁的my_mutex2,创在一个指针getNum2指向my_mutex2
		//getNum2.lock();//getNum2上锁,my_mutex2加锁,getNum2会自动解锁,所以不用unlock
		//...
		//3.2
		/*getNum2.unlock();
		处理一些非共享代码....
		处理结束.
		//接着上锁处理共享代码
		getNum2.lock();
		*/

		//-------------
		//3.3:try_lock
		//if(getNum2.try_lock()==true){}//返回true表示拿到锁了

		//-------------
		//3.4:release
		/*
		std::unique_lock<mutex>getNum2(my_mutex2);
		std::mutex *ptx=getNum2.release();//getNum2与my_mutex2解除关系,ptx与mutex2绑定
		//所以下面需要对mutex2进行手动解锁。
		*/

		//4.0转移所有权
		//std::unique_lock<mutex>getNum2(my_mutex2);
		//std::unique_lock<mutex>getNum3(std::move(getNum2));//Num2对于mutex2的所有权转移给Num3
		
		//4.1给return赋值
		unique_lock<mutex>getReNum = return_uqLock();
														   
			
			//封装判断
			bool result = getTheNumber(command);
			if (result == true)
			{
    
    
					cout << "outMsg running, get the number:" << command << endl;;
					//处理进行处理command数据
					//...
			}
			else 
			{
    
    
					cout << "outMsg is running,but the list is empty!" << endl;;
			}
				
		//}
		//2.2
		/*else
		{
					cout << "GetNum didn't get the lock" << ".We will do sth else." << endl;

		}*/

		//3.4:手动解锁
			//ptx->unlock();
	}
		
}
		
		
	

private:
	list<int>msgRecvQueue;
	mutex my_mutex;//我的互斥量
	mutex my_mutex2;//测试死锁


protected:
	bool getTheNumber(int& command)//取command地址,所以修改了command的数据
	{
    
    
		//unique_lock<mutex>getNum2(my_mutex2);
		

		
			if (!msgRecvQueue.empty())
			{
    
    

				command = msgRecvQueue.front();//Return the first value of the msgRecvQueue,but front doesn't check data
				msgRecvQueue.pop_front();//Delete the first number of the msgRQ

				return true;
			}

			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/108034529