future
经常被翻译为期物,它相当于函数的契约,在需要的时候可以通过这个契约来获取函数的返回值,他的创建方式有下面三种模式,分别对应着三种不同的使用场景
Async
async
可以返回 future
对象,其传入的参数是可调用对象及其参数
#include <iostream>
#include <future>
using namespace std;
void sayHello(){
<< "Hello" << endl;
cout }
int add(int a, int b){
return a + b;
}
int main(){
<void> a = async(sayHello);
future<int> b = async(add, 2, 3);
future.get();
a<< b.get() << endl;
cout }
生成的 future
的类型根据传入可调用对象的返回值而定,一般使用 auto
自动推导。future
可以通过 wait
方法来等待结果可以用,可以使用 get
获得可调用对象的返回值。
需要注意的是在生成 future
的时候并不一定同时生成一个线程运行对应的可调用对象,这个与其工作模式有关,可以通过 async
的第一个参数来指定工作模式,如果第一个参数为 std::launch::deferred
就表示只有调用 future
的 get
或者 wait
函数的时候,传入给 async
的函数才真正被调用。如果传入的第一个参数为 std::launch::async
表示在生成 future
的时候立即生成一个线程来运行可调用对象。默认的模式是 std::launch::deferred | std::launch::async
表示模式是可以根据编译器来选择的。
aysnc
可以用于分治算法的多线程计算。
Packaged_task
packaged_task
的初始化与 async
一种需要提供可调用对象,packaged_task
的类型根据可调用对象的返回值类型来定
#include <iostream>
#include <future>
using namespace std;
void sayHello(){
<< "Hello" << endl;
cout }
int add(int a, int b){
return a + b;
}
int main(){
<void()> task(sayHello);
packaged_task();
task}
packaged_task
本身是一个可执行对象,它执行的时候回导致内部的可执行对象一起执行。 packaged_task
有一个 get_future
方法来获取 future
对象。packaged_task
的作用就是将函数的调用与结果分离开来,一个线程用于调用,另一个线程通过 future
的 get
方法来获取调用的结果。
Promise
promise
提供了一种数据通信的方法
int main(){
<int>pr;
promise<int>f = pr.get_future();
future([&](){
thread w.set_value(0);
pr});
.detach();
w<< f.get() << endl;
cout }
在 promise
初始化的时候需要提供一个数据类型,这个数据类型是承若接下来要传入的数据类型,同 packaged_task
一样它有一个 get_future
方法来获取一个 future
,可以通过这个 future
的 get
方法来获取所存入的数据,如果没有存入数据数据则回堵塞。promise
可以通过 set_value
来存入数据。