前提:
在上一节中,我们使用了mutex的lock函数和unlock函数处理共享资源问题
这一节,我们学习使用 lock_guard来处理 共享资源问题。
lock_guard是啥?
是个类模版,这个类模版只能对mutex类型进行构造
例子:
lock_guard<mutex> mylock_guard(mymutex);
lock_guard的优点:
优点类似于智能指针,
当我们实例化一个 lock_guard后,不需要unlock()
lock_guard<mutex> mylock_guard(mymutex);
lock_guard工作原理
lock_guard是个类,那么就有构造函数和析构函数。
lock_guard的构造函数里面 执行了 mutex::lock();
lock_guard的析构函数里面 指向了 mutex::unlock();
这也是lock_guard类只用 实例化出来,就不会unlock()的原因,因为当lock_guard 对象析构的时候,会自动的unlock();
这也意味着在实现时,要特别注意lock_guard 对象是什么时候析构的。必要的时候,可以用{}包装起来。文章来源:https://www.toymoban.com/news/detail-799064.html
lock_guard 实例
改动代码如下:文章来源地址https://www.toymoban.com/news/detail-799064.html
class Teacher166 {
public:
//共享数据 存在list中
list<int> msgListQueue;
mutex mymutex;
int readcount = 0;//记录已经读取了多少个。
public:
//读取 共享数据的线程方法
void readfunc() {
while (true) {
//只要不为空,就可以读取数据
if (readcount >= 2000) {
break;
}
lock_guard<mutex> 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<mutex> mylock_guard(mymutex);//mylock_guard在这里创建出来,在mylock_guard的构造函数中,就已经对mymutex进行了lock()操作,等到mylock_guard的生命周期结束后会析构,这时候会调用mymutex的unlock()函数,实际上这里实例化对象 lock_guard<mutex> 不管名字是啥,只要里面参数是 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();
}
到了这里,关于50 C++ 多个线程共享资源问题fix方案二 ----- lock_guard类的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!