关于C++ 11 async和lambda 表达式的对this指针捕获的问题
lambda表达式中[this]根据cppreference,就是按引用捕获,并不保证this所指向的对象的生命周期。
而async在launch::async的flag下就是表示跳过当前函数,不会因为return了future之类的阻塞,而只会在future.get()的地方阻塞
实验程序
#include<iostream>
#include<string>
#include<thread>
#include<future>
#include<memory>
#include<mutex>
#include<cstring>
using namespace std;
class Base{
public:
int a;
string* s;
Base(int a):a(a){s=new string("goddd!!!");};
auto gene(){
return async(launch::async,[this]{
int i=0;while(1){i++;}
this_thread::sleep_for(std::chrono::milliseconds(2000));
this->a=30;
cout<<"in thread\n"<<*(this->s)<<endl;
return this;
});
}
auto gene2(){
return [this]{
//this_thread::sleep_for(std::chrono::milliseconds(1000));
cout<<"in thread gene2\n"<<*(this->s)<<endl;
return 7;
};
}
~Base(){delete s;s=nullptr;cout<<this<<" del\n";}
};
auto tr(){
Base bb(12);
auto x=bb.gene();
return x;
}
int main(){
tr();
cout<<"done "<<endl;//<<(cc.s)<<endl;
}

在tr()结束后,async会挂起,然后析构掉bb对象。后边async里边this所指向的字符串就是乱码输出了。(同一个程序因为多线程的缘故,跑几次的结果可能不同)
问题是如果main改成:
int main(){
Base bb(12);
auto x=bb.gene();
cout<<"done "<<endl;
}

那么done之后就卡在了async的部分,没有析构。主函数要等待async的调用结束之后才会彻底退出、析构对象。难道这时候对this的捕获造成了bb生命周期的延长?
应该不会的。我猜测是main对它的线程做了同步,要等所有async结束之后才能彻底结束。这看起来就像是async导致了bb的生命周期的延长一样。
浙公网安备 33010602011771号