std::async
std::future
#include<future>
std::async
是一个函数模板 , 用来启用一个异步任务 , 启动起来之后 , 返回一个std::future
(类模板)对象
启动一个异步任务 : 创建一个线程并开始执行对应的线程入口函数 , 返回一个std::future对象
std::future
里面就含有线程入口函数返回的结果( 线程返回结果 ) , 我们通过调用它的成员函数get()
来获取
std::future
提供了一种访问异步操作结果的机制 , 这个结果可能无法马上拿到 , 在将来线程执行结束后就能拿到
int run1(){
for(int i=0;i<=1e4;i++){
cout<<"thread_id : "<<std::this_thread::get_id()<<endl;
}
return 666;
}
int main(){
cout<<"main_thread_id : "<<std::this_thread::get_id()<<endl;
std::future<int> result = std::async(run1);//创建一个线程并开始执行
cout<<"continue...!"<<endl;
cout<<result.get()<<endl;//卡在这里,等待拿到结果
//get()只能调用一次
//result.wait();//等待线程返回 , 本身并不返回结果
return 0;
}
class A{
public:
int run1(int tem){
for(int i=0;i<=1e4;i++){
cout<<"thread_id : "<<std::this_thread::get_id()<<endl;
}
return 666;
}
};
int main(){
A a;
int tem=2;
std::future<int> result = std::async(A::run1,ref(a),tem);
cout<<result.get()<<endl;
return 0;
}
std::launch::deferred
通过向
std::async()
传递一个参数 , 该参数类型是std::lunnch
类型(枚举类型) , 来达到一些特殊目的
std::launch::deferred
表示线程入口函数调用被延迟到std::future
的wait()
或者get()
函数调用时才执行如果
wait()
或者get()
没有被调用 , 那么线程就不创建
std::launch::deferred
: 延迟调用 , 没有线程创建 , 直接在主函数中调用线程入口的函数
std::future<int> result = std::async(std::launch::deferred,A::run1,ref(a),tem);
std::launch::async
在调用
async
函数的时候就开始创建线程系统默认标记 , 就和不写是一样的
std::future<int> result = std::async(std::launch::async,A::run1,ref(a),tem);
std::packaged_task
打包任务 , 把任务包装起来
是一个类模板 , 它的模板参数是 各种可调用对象 ; 通过
std::packad_task
来把各种可调用对象包装起来 , 方便将作为线程入口函数调用
packaged_task
包装起来的可调用对象还可以直接调用 , 所以从这个角度来讲 ,packed_task
对象 , 也是一个可调用对象
#include<iostream>
#include<cstdio>
#include<thread>
#include<cstdlib>
#include<vector>
#include<list>
#include<queue>
#include<mutex>
#include<chrono>
#include<condition_variable>
#include<future>
using namespace std;
int run1(int tem){
cout<<"thread_id : "<<std::this_thread::get_id()<<endl;
return 666;
}
int main(){
cout<<"main_thread_id : "<<std::this_thread::get_id()<<endl;
std::packaged_task<int(int)> myjob(run1);//我们把函数mythread通过packaged_task包装起来,当然也可以写成lamda表达式
std::thread ttt(std::ref(myjob),1);//线程直接开始执行 , 第二个参数 作为线程入口函数的参数
ttt.join();//等待线程执行完毕
std::future<int> result = myjob.get_future();//std::future对象里包含有线程入口函数的返回结果,result保存了myjob的返回值
cout<<result.get()<<endl;
return 0;
}
int run1(int tem){
cout<<"thread_id : "<<std::this_thread::get_id()<<endl;
return 666;
}
int main(){
cout<<"main_thread_id : "<<std::this_thread::get_id()<<endl;
std::packaged_task<int(int)> myjob(run1);//我们把函数mythread通过packaged_task包装起来,当然也可以写成lamda表达式
myjob(3);//直接调用,直接在线程里执行
std::future<int> result = myjob.get_future();//std::future对象里包含有线程入口函数的返回结果,result保存了myjob的返回值
cout<<result.get()<<endl;
return 0;
}
std::promise
类模板
我们能够在某个线程中给它赋值 , 然后可以在其他线程中 , 把这个值取出来使用
#include<iostream>
#include<cstdio>
#include<thread>
#include<cstdlib>
#include<vector>
#include<list>
#include<queue>
#include<mutex>
#include<chrono>
#include<condition_variable>
#include<future>
using namespace std;
void run1(std::promise<int> &p,int tem){
cout<<"thread_id : "<<std::this_thread::get_id()<<endl;
tem++;
tem=((1<<tem) | tem);
for(int i=0;i<1e3;i++){
cout<<"i love China!"<<endl;
}
p.set_value(tem);//将结果保存到p对象中
}
void run2(std::future<int> &ful){
cout<<ful.get()<<endl;//直到线程run1执行结束才开始执行
cout<<"thread_id : "<<std::this_thread::get_id()<<endl;
}
int main(){
cout<<"main_thread_id : "<<std::this_thread::get_id()<<endl;
std::promise<int> mypro;//声明一个std::promise对象,保存值类型为int
std::thread tt(run1,std::ref(mypro),3);
//tt.join();
std::future<int> ful = mypro.get_future();//promise和future绑定,用于获取线程返回值
std::thread tt2(run2,std::ref(ful));
tt.join();
tt2.join();
return 0;
}