一、举个例子
1、洗澡和上厕所的案例
1.1、在上厕所的过程需要关门、防止他人看到或者防止洗澡的人进来,总之不能开着门上厕所吧。洗澡也一样,在洗澡的过程,需要关门,再洗澡。洗澡完后,开门出来,上厕所的人再上厕所。
1.2、如果上厕所和洗澡的人,不关上门,那不引发一些不敢想象的画面了。程序也一样引发一些异常。
如下:
#include<thread>
#include<iostream>
#include<string>
#include<mutex>
#include<list>
using namespace std;
using namespace this_thread;
class DoSomething
{
public:
void WC()
{
for(int i = 0; i < 1000; i++)
{
cout<<"上厕所"<<endl;
num.push_back(i);
}
}
void bath()
{
for(int i = 0; i < 1000; i++)
{
if(!num.empty())
{
cout<<"洗澡"<<endl;
num.pop_back();
}
else
{
cout<<"厕所在忙"<<endl;
}
}
}
protected:
list<int> num;
mutex mtx; //互斥量
};
int main()
{
DoSomething people;
thread t1(&DoSomething::WC,&people);
thread t2(&DoSomething::bath,&people);
t1.join();
t2.join();
return 0;
}
二、加锁
2.1、如果上厕所和洗澡的人,关上门,他人无法看一些画面了。程序也一样不会引发异常。
如下:
#include<thread>
#include<iostream>
#include<string>
#include<mutex>
#include<list>
using namespace std;
using namespace this_thread;
class DoSomething
{
public:
void WC()
{
for(int i = 0; i < 1000; i++)
{
unique_lock<mutex> unique(ntx); //unique_lock加锁
cout<<"上厕所"<<endl;
num.push_back(i);
}
}
void bath()
{
for(int i = 0; i < 1000; i++)
{
if(!num.empty())
{
unique_lock<mutex> unique(mtx); //unique_lock加锁
cout<<"洗澡"<<endl;
num.pop_back();
}
else
{
cout<<"厕所在忙"<<endl;
}
}
}
protected:
list<int> num;
mutex mtx; //互斥量
};
int main()
{
DoSomething people;
thread t1(&DoSomething::WC,&people);
thread t2(&DoSomething::bath,&people);
t1.join();
t2.join();
return 0;
}
三、 unique_lock 其他叁数
1、已经讲完了 unique_lock 加锁
//1,unique_lock加锁
unique_lock<mutex> unique(ntx); //unique_lock加锁
2、unique_lock 第二个叁数的第一个 adopt_lock 使用前、先进行lok操作,如果不加会引发中断
void WC()
{
for(int i = 0; i < 1000; i++)
{
unique.lock();
unique_lock<mutex> unique(ntx,adopt_lock);
cout<<"上厕所"<<endl;
num.push_back(i);
}
}
3、unique_lock 第二个叁数的第二个 defer_lock 需要手动 lock,创建是一个没有lock的锁,相当于只在门上安装了锁,没有上锁。也会引发异常。
void WC()
{
for(int i = 0; i < 1000; i++)
{
unique_lock<mutex> unique(ntx,defer_lock);
unique.lock();
cout<<"上厕所"<<endl;
num.push_back(i);
}
}
3.1、对于一个只在门上安装了锁,没有上锁的门,限于局部范围内方便程序设计。
比如:在做数据共享问题,有些没必要加锁的地方,没必要加锁;有些地方需要加锁、还是要加锁。
void WC()
{
for(int i = 0; i < 1000; i++)
{
unique_lock<mutex> unique(ntx,defer_lock);
cout<<"上厕所"<<endl;
unique.lock();
num.push_back(i);
unique.unlock();
unique.lock();
}
}
4、unique_lock 第二个叁数的第三个 try_to_lock 使用前、调用owns_lock()判断
void WC()
{
for(int i = 0; i < 1000; i++)
{
unique_lock<mutex> unique(ntx,try_to_lock);
cout<<"上厕所"<<endl;
if(unique.owns_lock())
{
num.push_back(i);
}
}
}