一、std::async,std::future
创建后台任务并返回值希望线程返回一个结果
std::async是个函数模板,用来启动一个异步任务,启动起来返回std::future创建一个线程并开始执行对应的线程函数返回std::future
std::future对象里面就有线程函数的返回结果,可能没办法马上得到,
但是在线程执行完毕的时候,就会返回结果了
#include<future>
using namespace std;
int mythread()
{
cout << "mythread() start. thread id =" << std::this_thread::get_id() << endl;
std::this_thread::sleep_for(2s);//休息2秒
cout << "mythread() end. thread id =" << std::this_thread::get_id() << endl;
return 5;
}
int main()
{
cout << "main id = " << std::this_thread::get_id() << endl;
std::future<int> result = std::async(mythread);
cout << "continue.... " << endl;
cout << result.get() << endl;//只能调用一次,调用多次报异常
}
可以通过额外向std::async()传递一个参数,该参数类型是std::launch类型(枚举类型),来达到一些特殊的目的。
比如std:launch::deferred:表示线程入口函数调用被延迟到std::future的wait()或者get()函数调用时才执行
如果没调用get()或者wait(),那么线程根本就没有创建。
并且没有新线程的创建,是在主线程里执行的
class A {
public:
int mythread(int mypar)
{
cout << mypar << endl;
cout << "mythread() start. thread id =" << std::this_thread::get_id() << endl;
std::this_thread::sleep_for(2s);//休息2秒
cout << "mythread() end. thread id =" << std::this_thread::get_id() << endl;
return 5;
}
};
int main()
{
A a;
int tmpper = 12;
cout << "main id = " << std::this_thread::get_id() << endl;
std::future<int> result = std::async(std::launch::deferred,&A::mythread,&a,tmpper);//第二个是引用保证是原对象
cout << "continue.... " << endl;
//cout << result.get() << endl;
}
std::launch::async
则是创建一个子线程,并且立即执行。
async()函数默认的就是async。
std::packaged_task:打包任务,把任务包装起来
是个类模板,模板参数是各种可调用对象。通过packaged_task来把各种可调用对象包装起来,方便将来作为线程入口函数用来调用
#include<future>
using namespace std;
int mythread(int mypar)
{
cout << mypar << endl;
cout << "mythread() start. thread id =" << std::this_thread::get_id() << endl;
std::this_thread::sleep_for(2s);//休息2秒
cout << "mythread() end. thread id =" << std::this_thread::get_id() << endl;
return 5;
}
int main()
{
cout << "main id = " << std::this_thread::get_id() << endl;
std::packaged_task<int(int)> mypt(mythread);
std::thread t1(std::ref(mypt),1);
t1.join();
std::future<int> result = mypt.get_future();
cout << result.get() << endl;
cout << "continue.... " << endl;
}
#include<future>
using namespace std;
int main()
{
cout << "main id = " << std::this_thread::get_id() << endl;
//packaged_task包装起来的可调用对象还可以直接调用,所以从这个角度来讲,packaged_task对象也是一个可调用对象
std::packaged_task<int(int)> mypt([](int mypar) {
cout << mypar << endl;
cout << "mythread() start. thread id =" << std::this_thread::get_id() << endl;
std::this_thread::sleep_for(2s);//休息2秒
cout << "mythread() end. thread id =" << std::this_thread::get_id() << endl;
return 5;
});
mypt(105);//相当于函数调用
std::future<int> result = mypt.get_future();
cout << result.get() << endl;
cout << "continue.... " << endl;
return 0;
}
vector<packaged_task<int(int)>> mytasks;
int main()
{
cout << "main id = " << std::this_thread::get_id() << endl;
//packaged_task包装起来的可调用对象还可以直接调用,所以从这个角度来讲,packaged_task对象也是一个可调用对象
std::packaged_task<int(int)> mypt([](int mypar) {
cout << mypar << endl;
cout << "mythread() start. thread id =" << std::this_thread::get_id() << endl;
std::this_thread::sleep_for(2s);//休息2秒
cout << "mythread() end. thread id =" << std::this_thread::get_id() << endl;
return 5;
});
mytasks.push_back(std::move(mypt));//入容器,mypt为空
//...
std::packaged_task<int(int)>mypt2;
auto iter = mytasks.begin();
mypt2 = std::move(*iter);
mytasks.erase(iter);//删除第一个元素,迭代器失效
mypt2(23);
std::future<int> result = mypt2.get_future();
cout << result.get() << endl;
cout << "continue.... " << endl;
return 0;
}
#include<future>
using namespace std;
//std::promise 类模板
//能够在某个线程中给它赋值,然后在其他线程中把这个值取出来用。
//总结:通过promise保存一个值,在将来某个时刻我们通过一个future绑定到这个promise来获取这个绑定的值
void mythread(std::promise<int>&temp, int cal)
{
cal++;
this_thread::sleep_for(2s);
int result = cal;//保存结果
temp.set_value(result);//结果保存到temp对象中,
return;
}
void mythread2(std::future<int> &temp)
{
auto result = temp.get();
cout << "mythread2 result " << result << endl;
}
int main()
{
cout << "main id = " << std::this_thread::get_id() << endl;
//packaged_task包装起来的可调用对象还可以直接调用,所以从这个角度来讲,packaged_task对象也是一个可调用对象
std::promise<int>myprom;
std::thread t(mythread, std::ref(myprom), 180);
t.join();
//获取结果值
std::future<int> fu1 = myprom.get_future();//获取返回值
std::thread t2(mythread2, std::ref(fu1));
t2.join();
cout << "continue.... " << endl;
return 0;
}