std::async和std::future创建后台任务并返回值
一,前言
std::async是一个函数模板,用来启动一个异步任务,启动起来的异步任务会返回一个std::futured对象,这个对象里面有异步任务的返回结果。
int func(){
std::this_thread::sleep_for(std::chrono::seconds(1));
return 0;
}
int main(){
std::future<int> result = std::async(func);
cout << result.get() << endl;
}
- 这里的result.get()和线程join()类似,程序会阻塞到当前行直到异步任务返回。想比线程我们可以拿到返回值
- 也可以使用result.wait()和join()一样,获取不到返回值
二,std::async 额外参数
- auto result = std::async(std::launch::deferred,func) // 一直延迟到主线程调用wait()或get()时才启动异步任务,如果主程序没有调用get()或wait(),则什么事没有发生
- auto result = std::async(std::launch::async,func) //系统必须创建出新线程
- auto result = std::async(std::launch::async | std::launch::deferred,func) //系统根据硬件资源决定是否创建线程
- auto result = std::async(func); 和3一样由系统决定
三,std::packaged_task类模板
int func(int a){
std::this_thread::sleep_for(std::chrono::seconds(1));
return a;
}
int main(){
std::packaged_task<int(int)> mypt(func);
std::thread t(std::ref(mypt),1);
t.join();
std::future<int> result = mypt.get_future(mypt);
cout << result.get() << endl;
}
四,promise类模板
主要用于线程间通信
void func(std::promise<int>& tmp,int calc){
//做一系列复杂的运算
int result = calc;
tmp.set_value(result);
}
void func2(std::future<int>& tmpf){
auto result = tmpf.get();
cout << result << endl;
}
int main(){
std::promise<int> myprom;
std::thread t(func,std::ref(myprom),100);
t.join();
std::future<int> ful = myprom.get_future();
//auto result = ful.get();//只能get一次
std::thread t2(func2,std::ref(ful));
t2.join();
}
五,future成员函数
int func(){
std::this_thread::sleep_for(std::chrono::seconds(1));
return 1;
}
int main(){
std::future<int> result = std::async(func);
std::future _status status = result.wait_for(std::chrono::seconds(1));
if(status == std::future_status::timeout){
//异步任务超时还没有结束
cout << result.get() << endl;
}else if(status == std::future_status::ready){
//异步任务成功返回
cout << result.get() << endl;
}else if(status == std::future_status::deferred){
//异步任务被延迟创建
cout << result.get() << endl;//这会导致在主线程中执行线程入口函数,
//个人感觉就跟调用普通函数是没啥区别
}
}
六,shared_future类模板
由于get()函数被设计为移动语义,所以如果有多个线程想要获取函数线程返回值,就需要使用shared_future
int main(){
std::packaged_task<int(int)> mypt(func);
std::thread t1(std::ref(mypt));
t1.join();
std::shared_future<int> result_s(mypt.get_future());
auto result = result_s.get();
auto result2 = result_s.get(); //可以get多次
std::thread t2(func,std::ref(result_s));
t2.get();
}