template< class Function, class... Args > std::future<std::invoke_result_t<std::decay_t<Function>, std::decay_t<Args>...>> async( std::launch policy, Function&& f, Args&&... args ); |
The template function async runs the function f asynchronously (potentially in a separate thread which may be part of a thread pool) and returns a std::future that will eventually hold the result of that function call.
译文:模板函数async异步运行函数f(可能在单独的线程中,可能是线程池的一部分),并返回一个std::future,它将最终保存该函数调用的结果。
1.根据特定的启动策略(std::launch::async | std::launch::deferred)调用带有参数args的函数f:
2.If the async flag is set (i.e. (policy & std::launch::async) != 0), then async executes the callable object f on a new thread of execution (with all thread-locals initialized) as if spawned by std::thread(std::forward<F>(f), std::forward<Args>(args)...), except that if the function f returns a value or throws an exception, it is stored in the shared state accessible through the std::future that async returns to the caller.
译文:如果异步标志设置(例如设置了 (policy & std::launch::async) != 0),然后异步执行f可调用对象的一个新线程执行(所有线程局部初始化),就像催生了std::线程(std::< f >(f),std::转发<参数>(Args)……),除了,如果函数返回一个值或者抛出一个异常,存储在共享状态可以通过std::future异步返回给调用者。
3.If the deferred flag is set (i.e. (policy & std::launch::deferred) != 0), then async converts f and args... the same way as by std::thread constructor, but does not spawn a new thread of execution. Instead, lazy evaluation is performed: the first call to a non-timed wait function on the std::future that async returned to the caller will cause the copy of f to be invoked (as an rvalue) with the copies of args... (also passed as rvalues) in the current thread (which does not have to be the thread that originally called std::async). The result or exception is placed in the shared state associated with the future and only then it is made ready. All further accesses to the same std::future will return the result immediately.
译文:如果设置推迟deferred标志 (policy & std::launch::deferred) != 0),然后异步转换f和args…与std::thread构造函数相同,但不会产生新的执行线程。相反,执行延迟计算:对std::future中的非定时等待函数的第一次调用返回的是async返回给调用者的,这将导致调用f的副本(作为右值)包括参数args的副本…(也作为值传递)在当前线程(不一定是最初称为std::async的线程)中。结果或异常被放置在与将来相关联的共享状态中,然后才准备好。结果或异常被放置在与将来相关联的共享状态中,然后才准备好。所有对同一std::future的进一步访问将立即返回结果。
example 1:
#include <iostream>
#include <vector>
#include <algorithm>
#include <numeric>
#include <future>
template <typename RandomIt>
int parallel_sum(RandomIt beg, RandomIt end)
{
auto len = end - beg;
if (len < 1000)
return std::accumulate(beg, end, 0);
RandomIt mid = beg + len/2;
auto handle = std::async(std::launch::async,
parallel_sum<RandomIt>, mid, end);
int sum = parallel_sum(beg, mid);
return sum + handle.get();
}
int main()
{
std::vector<int> v(10000, 1);
std::cout << "The sum is " << parallel_sum(v.begin(), v.end()) << '\n';
}
结果返回:1000.
example 2:
#include <future>
#include <iostream>
#include <stout/stringify.hpp>
bool is_prime(int x)
{
for (int i=0; i<x; i++)
{
if (x % i == 0)
return false;
}
return true;
}
int main()
{
std::future<bool> fut = std::async(is_prime, 700020007);
std::cout << "please wait";
std::chrono::milliseconds span(100);
while (fut.wait_for(span) != std::future_status::ready)
std::cout << ".";
std::cout << std::endl;
bool ret = fut.get();
std::cout << "final result: " << stringify(ret) << std::endl;
return 0;
}
std::future可以从异步任务中获取结果,一般与std::async配合使用,std::async用于创建异步任务,实际上就是创建一个线程执行相应任务。std::async会首先创建线程执行is_prime(700020007), 任务创建之后,std::async立即返回一个std::future对象。
主线程既可使用std::future::get获取结果,如果调用过程中,任务尚未完成,则主线程阻塞至任务完成。
主线程也可使用std::future::wait_for等待结果返回,wait_for可设置超时时间,如果在超时时间之内任务完成,则返回std::future_status::ready状态;如果在超时时间之内任务尚未完成,则返回std::future_status::timeout状态。