我们知道,如果我们有一个捕获类成员的lambda,并且在释放类对象之后异步调用了lambda,则它应该崩溃。但是,如果lambda捕获“ this”,并在释放类对象后调用this-> memFunc(),则它似乎可以正常工作。我不明白为什么它不会崩溃。参见代码v1。
class A:
{
public:
int func()
{
std::ofstream myfile("example.txt");
if (myfile.is_open())
{
myfile << "Write from child thread.\n";
myfile.close();
}
else
{
std::cout << "Unable to open file";
}
}
void detach()
{
std::thread t([this]() {
std::this_thread::sleep_for(std::chrono::milliseconds(3000));
func();
});
t.detach();
}
};
int main()
{
{
A a;
a.detach();
}
std::cout << "main end" << std::endl;
std::this_thread::sleep_for(std::chrono::milliseconds(5000));
return 0;
}
v2:
#define RETURN_FROM_LAMBDA_IF_DEAD(x) \
auto sharedThis = x.lock(); \
if(!sharedThis) \
return;
class A: public std::enable_shared_from_this<A>
{
public:
int func()
{
std::ofstream myfile("example.txt");
if (myfile.is_open())
{
myfile << "Write from child thread.\n";
myfile.close();
}
else
{
std::cout << "Unable to open file";
}
}
void detach()
{
std::thread t([weakThis = weak_from_this(), this]() {
RETURN_FROM_LAMBDA_IF_DEAD(weakThis);
std::this_thread::sleep_for(std::chrono::milliseconds(3000));
func();
});
t.detach();
}
};
int main()
{
{
A a;
a.detach();
}
std::cout << "main end" << std::endl;
std::this_thread::sleep_for(std::chrono::milliseconds(5000));
return 0;
}
A类具有成员函数detach(),它将创建一个子线程。子线程接受一个lambda,其中将调用A的成员函数func()。
当主线程打印“ main end”时,应释放对象a,因此当其子线程调用a的func()时,它应崩溃。但是a的func()运行正常,并且成功创建了“ example.txt”。
为什么即使a被释放后仍可以调用a的func()?
为确保子线程调用func()时已释放a,我添加了弱指针检查,请参见代码v2。
这一次,子线程直接从lambda返回,并且不调用func()。这意味着当子线程启动运行时,对象a确实已被释放。
有人可以帮忙做些指示吗?