在上一节中,我们使用了mutex的lock函数和unlock函数处理共享资源问题
这一节,我们学习使用 lock_guard来处理 共享资源问题。
是个类模版,这个类模版只能对mutex类型进行构造
例子:
lock_guard
优点类似于智能指针,
当我们实例化一个 lock_guard后,不需要unlock()
lock_guard
lock_guard是个类,那么就有构造函数和析构函数。
lock_guard的构造函数里面 执行了 mutex::lock();
lock_guard的析构函数里面 指向了 mutex::unlock();
这也是lock_guard类只用 实例化出来,就不会unlock()的原因,因为当lock_guard 对象析构的时候,会自动的unlock();
这也意味着在实现时,要特别注意lock_guard 对象是什么时候析构的。必要的时候,可以用{}包装起来。
改动代码如下:
class Teacher166 {
public:
//共享数据 存在list中
list msgListQueue;
mutex mymutex;
int readcount = 0;//记录已经读取了多少个。
public:
//读取 共享数据的线程方法
void readfunc() {
while (true) {
//只要不为空,就可以读取数据
if (readcount >= 2000) {
break;
}
lock_guard mylock_guard(mymutex);//mylock_guard在这里创建出来,在mylock_guard的构造函数中,就已经对mymutex进行了lock()操作,等到mylock_guard的生命周期结束后会析构,这时候会调用mymutex的unlock()函数
if (!msgListQueue.empty()) {
int readvalue = msgListQueue.front();//每次都读取第一个
cout << "读取到的值为" << readvalue << " readcount = " << readcount << endl;
msgListQueue.pop_front();//删除第一个元素
readcount++;
}
else {
cout << "没有读取到值" << endl;
}
}
}
//写入 共享数据的线程方法
void writefunc() {
for (size_t i = 0; i < 1000; i++)
{
lock_guard mylock_guard(mymutex);//mylock_guard在这里创建出来,在mylock_guard的构造函数中,就已经对mymutex进行了lock()操作,等到mylock_guard的生命周期结束后会析构,这时候会调用mymutex的unlock()函数,实际上这里实例化对象 lock_guard 不管名字是啥,只要里面参数是 mymutex就可以了,也就是说:只要是同一个 mutex
msgListQueue.push_back(i);//每次都写到末尾
cout << "写入元素的值为" << i << endl;
}
}
public:
Teacher166() {
cout << "Teacher166 构造方法 this = " << this << endl;
}
Teacher166(const Teacher166 & obj) {
cout << "Teacher166 copy 构造方法 this = " << this << " obj = " << &obj << endl;
}
~Teacher166() {
cout << "Teacher166 析构函数 this = " << this << endl;
}
};
void main() {
cout << "=========================" << endl;
Teacher166 tea1;
thread readthread1(&Teacher166::readfunc, &tea1);
thread writethread1(&Teacher166::writefunc, &tea1);
//thread 的构造方法第二个参数 可以是地址,如果是地址,那么 readthread1 和 writethread1的传递就是同一个 teacher
thread readthread2(&Teacher166::readfunc, &tea1);
thread writethread2(&Teacher166::writefunc, &tea1);
readthread1.join();
readthread2.join();
writethread1.join();
writethread2.join();
}