如下所示
- 主线程有一个类A,并且主线程启动后创建了一个子线程t1
- 子线程t1需要访问主线程类A的方法func
class A
{
public:
A(){cout<<"A()"<<endl;}
~A(){cout<<"~A()"<<endl;}
void func()
{
cout<<"this is a func"<<endl;
}
};
void handler(A* pw)
{
pw->func();
}
void test()
{
A* p=new A();
thread t1(handler,p);
delete p;
t1.join();
}
目前来看,子线程t1访问主线程中类A的方法没什么问题。但是我们稍微修改一下代码,让子线程休眠2s,如下所示
class A
{
public:
A(){cout<<"A()"<<endl;}
~A(){cout<<"~A()"<<endl;}
void func()
{
cout<<"this is a func"<<endl;
}
};
void handler(A* pw)
{
std::this_thread::sleep_for(std::chrono::seconds(2));//休眠2s
pw->func();
}
void test()
{
A* p=new A();
thread t1(handler,p);
delete p;
t1.join();
}
如图所示,由于子线程休眠了2s,因此主线程释放掉了指针p后,子线程才开始执行。那么问题来了,指针p所指向的资源对象A已经被释放掉了,子线程再去访问它,这样显然是不合理的。
为了解决这种问题,我们引入智能指针的处理方式
#include<iostream>
#include<thread>
#include<memory>
using namespace std;
class A
{
public:
A(){cout<<"A()"<<endl;}
~A(){cout<<"~A()"<<endl;}
void func()
{
cout<<"this is a func"<<endl;
}
};
void handler(weak_ptr<A> pw)
{
std::this_thread::sleep_for(std::chrono::seconds(2));//休眠2s
shared_ptr<A> ps=pw.lock();
if(ps)
{
ps->func();
}else{
cout<<"A的资源已经被释放掉了"<<endl;
}
}
void test()
{
{
shared_ptr<A> p(new A());
thread t1(handler,p);
t1.detach();
}
std::this_thread::sleep_for(std::chrono::seconds(20));//休眠5s
}
int main()
{
test();
return 0;
}
在以上处理方式中,由于weak_ptr可以检测资源的存活状态,也就是说,如果类A的资源仍旧存在,那么pw.lock()就会返回一个强指针从而访问资源,否则就说明类A的资源已经不存在了,就不能再访问它,这样就解决了多线程访问共享资源的线程安全问题。