概念
std::future 提供了一种异步访问结果的机制。一般与std::async配合使用,std::async用于创建异步任务,实际上就是创建一个线程执行相应任务。
相关函数
get()
获取future对象的结果,如果还没有返回结果,就阻塞,直到返回结果。
valid()
检查future对象是否为共享状态。如是共享状态,则返回true,否则返回false。在非共享状态的future上调用任何析构函数、移动 赋值运算符或valid以外的成员函数,行为未定义。
wait()
无返回值。阻塞直到结果变得可用,调用后valid()==true
wait_for()
等待结果变得可用,阻塞直至指定的时间,或者直到结果可用。
返回值:
future_status:deferred 要计算结果的函数仍未启动
future_status:ready 就绪
future_status:timeout 超时
wait_until()
等待结果变得可用,阻塞到指定的时刻,或者直到结果可用。
返回值同上。
future与shared_future的比较
- future只能调用一次get,如果已经get过,其共享状态就会被释放,再次使用就会报错。
- shared_future 在get后,不会释放共享状态,可以拷贝,共享某个共享状态的最终结果。
- shared_future 可以通过 future 对象隐式转换
- 也可以通过显式调用std::future::share显式转换。
- 注意:当future转换为shared_future后,原future对象就会变的无效。
get()和wait()的使用
#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 do_check_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(do_check_prime, 194232491);
std::cout << "Checking...\n";
fut.wait();
std::cout << "\n194232491 ";
if (fut.get()) // guaranteed to be ready (and not block) after wait returns
std::cout << "is prime.\n";
else
std::cout << "is not prime.\n";
return 0;
}
wait_until()使用
// wait_until 使用
#include <iostream>
#include <future>
#include <thread>
#include <chrono>
int main()
{
std::chrono::system_clock::time_point two_seconds_passed
= std::chrono::system_clock::now() + std::chrono::seconds(2);
// 做出花 1 秒完成的 future
std::promise<int> p1;
std::future<int> f_completes = p1.get_future();
std::thread([](std::promise<int> p1)
{
std::this_thread::sleep_for(std::chrono::seconds(1));
p1.set_value_at_thread_exit(9);
},
std::move(p1)
).detach();
// 做出花 5 秒完成的 future
std::promise<int> p2;
std::future<int> f_times_out = p2.get_future();
std::thread([](std::promise<int> p2)
{
std::this_thread::sleep_for(std::chrono::seconds(5));
p2.set_value_at_thread_exit(8);
},
std::move(p2)
).detach();
std::cout << "Waiting for 2 seconds..." << std::endl;
if(std::future_status::ready == f_completes.wait_until(two_seconds_passed))
{ std::cout << "f_completes: " << f_completes.get() << "\n"; }
else
{ std::cout << "f_completes did not complete!\n"; }
if(std::future_status::ready == f_times_out.wait_until(two_seconds_passed))
{ std::cout << "f_times_out: " << f_times_out.get() << "\n"; }
else
{ std::cout << "f_times_out did not complete!\n"; }
std::cout << "Done!\n";
}
/*
输出
Waiting for 2 seconds...
f_completes: 9
f_times_out did not complete!
Done!
*/
future对象的几种状态
std::future_status status;
do
{
// 我们对预言的实现的时限忍耐是很有限的,我们只能忍一秒
status = fu.wait_for(std::chrono::seconds(1));
if(status == std::future_status::deferred) //异步操作还没开始
std::cout << "deferred" << std::endl; // 那还可以等等
else if(status == std::future_status::timeout) //异步操作超时
std::cout << "timeout" << std::endl; // 抡起大棒打骗子
else if(status == std::future_status::ready) //异步操作已完成
std::cout << "ready" << std::endl; // 真的发生了!
}while(status != std::future_status::ready);
future与shared_future的转换
// 隐式转换
// 将std::shared_future<int>调整为std::future<int>也是正确的
std::shared_future<int> f1 = std::async(std::launch::async, []() { return fib(20); });
// 显式转换
// 通过std::future移动构造std::shared_future对象
std::promise<void> ready_promise;
std::shared_future<void> ready_future(ready_promise.get_future());
// 从 promise 获取 future,并赋值给shared_future
promise<int> prom;
shared_future<int> sf1 = std::move(prom.get_future());
// 调用std::future::share显式转换
std::future<int> fut = std::async(do_get_value);
std::shared_future<int> shared_fut = fut.share();