关于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的生命周期的延长一样。

posted @ 2021-12-07 14:12  pagedown  阅读(775)  评论(0)    收藏  举报