1. 程式人生 > >c++11 std::async

c++11 std::async

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狀態。