最終更新日時:
が更新

履歴 編集

function template
<future>

std::async(C++11)

namespace std {
  template <class F, class... Args>
  future<typename result_of<F(Args...)>::type>
    async(F&& f, Args&&... args);                // (1) C++11

  template <class F, class... Args>
  future<
    typename result_of<
      typename decay<F>::type(typename decay<Args>::type...)
    >::type
  > async(F&& f, Args&&... args);                // (1) C++14

  template <class F, class... Args>
  future<typename result_of<F(Args...)>::type>
    async(launch policy, F&& f, Args&&... args); // (2) C++11

  template <class F, class... Args>
  future<
    typename result_of<
      typename decay<F>::type(typename decay<Args>::type...)
    >::type
  > async(launch policy, F&& f, Args&&... args); // (2) C++14
}

概要

関数を非同期実行する。

この関数は、指定された関数を非同期実行し、結果値を取得するためのfutureオブジェクトを返す。

返されたfutureオブジェクトのget()もしくはwait()を呼び出すことにより、非同期実行の完了を待機する。

要件

  • 関数オブジェクトFおよびArgs...の各型が、is_move_construcitble<T>::value == trueであること。
  • INVOKE(DECAY_COPY(std::forward<F>(f)), DECAY_COPY(std::forward<Args>(args))...)が可能であること。

効果

この関数は、パラメータpolicyで指定された実行ポリシーの値によって振る舞いを変える。

policyを指定しない場合はlaunch::async | launch::deferredとなり、どちらの実行ポリシーが選択されるかは実装定義となる。

各実行ポリシーの振る舞いは以下のようになる:

  • policy & launch::async0じゃない場合、新たなスレッドで関数オブジェクトfargs...を渡して実行する
    • ( INVOKE(DECAY_COPY(std::forward<F>(f)), DECAY_COPY(std::forward<Args>(args))...) )
    • 関数オブジェクトfの戻り値が、この関数の戻り値であるfutureオブジェクトとの共有状態に書き込まれる。
    • 関数オブジェクトfの内部で例外が投げられた場合は、共有状態に投げられた例外が設定される。
  • policy & launch::deferred0じゃない場合、関数オブジェクトfをその場では実行せず、遅延状態にする
    • (DECAY_COPY(std::forward<F>(f))DECAY_COPY(std::forward<Args>(args))...futureオブジェクトとの共有状態に格納する)。
    • この関数の戻り値であるfutureオブジェクトのget()もしくはwait()が呼び出されるタイミングで、関数オブジェクトfargs...を渡して実行する。
  • 有効な実行ポリシーが指定されていない場合(整数値をlaunch型にキャストするような状況)、その動作は未定義(C++14)。

戻り値

非同期実行される関数オブジェクトfの結果値取得のためのfutureオブジェクトを返す。

例外

この関数は、以下のerror conditionを持つfuture_error例外オブジェクトを送出する可能性がある:

#include <iostream>
#include <future>
#include <thread>

int foo() { std::cout << "executes foo()\n"; return 3; }

int main()
{
  // 新たなスレッドで関数foo()を非同期実行
  {
    std::cout << "invokes std::async(std::launch::async, foo)" << std::endl;
    std::future<int> f = std::async(std::launch::async, foo);
    std::this_thread::sleep_for(std::chrono::milliseconds(10));
    std::cout << "main thread: slept for 10 msec\n";
    // 非同期実行の結果を取得
    int result = f.get();
    std::cout << "foo() = " << result << std::endl;
  }

  std::cout << std::endl;

  // 関数fを遅延状態で非同期実行
  {
    // この段階では関数foo()を実行しない
    std::cout << "invokes std::async(std::launch::deferred, foo)" << std::endl;
    std::future<int> f = std::async(std::launch::deferred, foo);
    std::this_thread::sleep_for(std::chrono::milliseconds(10));
    std::cout << "main thread: slept for 10 msec\n";

    // 非同期実行の結果を取得
    // この段階で関数foo()を実行
    int result = f.get();
    std::cout << "foo() = " << result << std::endl;
  }
  return 0;
}

出力

invokes std::async(std::launch::async, foo)
executes foo()
main thread: slept for 10 msec
foo() = 3

invokes std::async(std::launch::deferred, foo)
main thread: slept for 10 msec
executes foo()
foo() = 3

バージョン

言語

  • C++11

処理系

参照