A future is an object that can retrieve a value from some provider object or function, properly synchronizing this access if in different threads.
"Valid" futures are future objects associated to a shared state, and are constructed by calling one of the following functions: 通过一下几种方式构造一个future:
future objects are only useful when they are valid. Default-constructed future objects are not valid (unless move-assigned a valid future).
Calling future::get on a valid future blocks the thread until the provider makes the shared state ready (either by setting a value or an exception to it). This way, two threads can be synchronized by one waiting for the other to set a value.
Example:
// future example
#include <iostream> // std::cout
#include <future> // std::async, std::future
#include <chrono> // std::chrono::milliseconds
// a non-optimized way of checking for prime numbers:
bool is_prime (int x) {
for (int i=2; i<x; ++i) if (x%i==0) return false;
return true;
}
int main ()
{
// call function asynchronously:
std::future<bool> fut = std::async (is_prime,444444443);
// do something while waiting for function to set future:
std::cout << "checking, please wait";
std::chrono::milliseconds span (100);
while (fut.wait_for(span)==std::future_status::timeout)
std::cout << '.' << std::flush;
bool x = fut.get(); // retrieve return value
std::cout << "\n444444443 " << (x?"is":"is not") << " prime.\n";
return 0;
}
Possible output (may take more or less time):
|
std::promise
promise 对象可以保存某一类型 T 的值,该值可被 future 对象读取(可能在另外一个线程中),因此 promise 也提供了一种线程同步的手段。在 promise 对象构造时可以和一个共享状态(通常是std::future)相关联,并可以在相关联的共享状态(std::future)上保存一个类型为 T 的值。
- promise 对象是异步 Provider,它可以在某一时刻设置共享状态的值。
- future 对象可以异步返回共享状态的值,或者在必要的情况下阻塞调用者并等待共享状态标志变为 ready,然后才能获取共享状态的值。
例子:
主线程向子线程承诺传递一个参数(std::promise<int> p),子线程先接受这个承诺(std::future f = p.get_future()),然后一直等待(f.get()),直到主线程履行承诺(p.set_value()),子线程才继续向下执行。
#include<future>
int factorial(std::future<int>& f){
int res = 1;
// 子线程一直在这里等待,直到主线程传给它这个参数
int N = f.get();
for(int i = N; i > 1; i--){
res *= i;
}
return res;
}
int main(){
int x;
// 主线程向子线程保证,我会传给你一个参数,但是我现在没有这个参数,未来我会传给你。
std::promise<int> p;
std::future<int> f_to = p.get_future();
std::future<int> f_from = std::async(factorial, std::ref(f_to));
//主线程履行承诺,传给子线程一个参数:
p.set_value(4);
x = f_from.get();
std::cout << "factorial of " << N << " is " << x << std::endl;
return 0;
}
主线程完全可以不履行这个承诺。如果这种情况发生,那么子线程会出std::future_erro::broken_promise的错误。如果主线程知道自己无法履行承诺,那么应该这样做:
#include<future>
int factorial(std::future<int>& f){
int res = 1;
// 子线程一直在这里等待,但是这次它发现主线程并没有履约,而是传来一个消息,于是子线程得到一个run time error消息并退出。
int N = f.get();
for(int i = N; i > 1; i--){
res *= i;
}
return res;
}
int main(){
int x;
// 这里,主线程向子线程保证,我会传给你一个参数,但是我现在没有这个参数,未来我会传给你。
std::promise<int> p;
std::future<int> f_to = p.get_future();
std::future<int> f_from = std::async(factorial, std::ref(f_to));
// 后来主线程发现自己没有办法履行承诺,就传给子线程一个消息:
p.set_exception(std::make_exception_ptr(std::runtime_errpr("Sorry I cannot keep my promise")));
x = f_from.get();
std::cout << "factorial of " << N << " is " << x << std::endl;
return 0;
}
Ref:
C++11中std::future的使用_fengbingchun的博客-CSDN博客_c++ future
C++11之std::future对象使用说明_Jimmy1224的博客-CSDN博客_c++ future