GV

GeezerVison

The World Wide Web, restored to 800 pixels of glory.

Home|About|Gaming cabinet|Archives|How it works|Starter sites

On this site

  • cpprefjp - C++日本語リファレンス
  • GitHub Project

This view

  • Original page
  • New address

GeezerVison is showing cpprefjp.github.io — std::async - cpprefjp C++日本語リファレンス

  1. リファレンス
  2. future
  3. async

最終更新日時: 2026年09月19日 21時31分51秒 (JST)
rotarymars が更新

履歴 編集

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<invoke_result_t<decay_t<F>, decay_t<Args>...>>
    async(F&& f, Args&&... args);                // (1) C++17
  template <class F, class... Args>
  [[nodiscard]]
  future<invoke_result_t<decay_t<F>, decay_t<Args>...>>
    async(F&& f, Args&&... args);                // (1) C++20
  future<invoke_result_t<decay_t<F>, decay_t<Args>...>>
    async(F&& f, Args&&... args);                // (1) C++26


  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
  template <class F, class... Args>
  future<invoke_result_t<decay_t<F>, decay_t<Args>...>>
    async(launch policy, F&& f, Args&&... args); // (2) C++17
  template <class F, class... Args>
  [[nodiscard]]
  future<invoke_result_t<decay_t<F>, decay_t<Args>...>>
    async(launch policy, F&& f, Args&&... args); // (2) C++20
  future<invoke_result_t<decay_t<F>, decay_t<Args>...>>
    async(launch policy, F&& f, Args&&... args); // (2) C++26
}

概要

関数を非同期実行する。

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

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

要件

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

効果

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

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

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

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

戻り値

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

例外

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

  • resource_unavailable_try_again : launch::asyncが指定され、新たなスレッドを起動しようとしたができなかった

また、内部データ構造のメモリ確保に失敗した場合、std::bad_allocが投げられる可能性がある。

launch::asyncポリシーを指定した場合の注意点

戻り値

launch::asyncを指定してこの関数を呼び出した場合のみ、戻り値のfutureオブジェクトはそのデストラクタにおいて、指定された関数の終了を待機する(おそらく、wait()を呼ぶ)。

すなわち、launch::asyncを指定した場合には戻り値を何かしらの形で受けておかないとこの関数は同期的に実行されているかのように振舞う。また、戻り値を何かしらの形で受けた場合でもそのスコープを抜ける際に指定された関数の終了を待機する。この挙動はクラスのメンバ変数に保存する等、外部スコープに持ち出したとしても変わらない。

//これらの呼び出しは別スレッドで実行されるが、同期的に呼び出される
std::async(std::launch::async, []{ f(); }); //f()が完了するまではこの行で待機する
std::async(std::launch::async, []{ g(); }); //g()の呼び出しは必ずf()の終了後、g()の完了まで処理はブロックされる

//次の様に戻り値を受けておけば、それぞれ非同期的に実行される
{
  auto futuref = std::async(std::launch::async, []{ f(); }); //f()の完了を待機しない
  auto futureg = std::async(std::launch::async, []{ g(); }); //g()の呼び出しはf()の完了前かもしれない

  /*何か他の処理*/

} //このブロックスコープを抜ける際に、f()とg()の完了を待機する

なお、この関数にlaunch::async指定して得たfutureオブジェクトのみがデストラクタでの共有状態の完了待機を行う。その他の方法で取得したfutureオブジェクトはこのような振舞をしない。

MSVCの実装とスレッドローカルストレージの利用

MSVCにおけるlaunch::async指定した際のこの関数の実装は、Windowsの提供するスレッドプールのスレッドを用いて処理を実行するため、新しいスレッドを起動せず、処理スレッドは終了されない。

このため、スレッドローカルストレージを利用している場合、あるスレッドにおける同じ処理の1回目の呼び出しではスレッドローカルストレージ内のオブジェクトは破棄されず、2回目以降の呼び出しではスレッドローカルストレージ内オブジェクトの初期化処理は実行されない。
また、どのスレッドが呼ばれるかはおそらくランダムであるため、違うスレッドローカルストレージにある同じ名前のオブジェクトを利用していることになる可能性もある。
Windows環境においてMSVC実装の本関数とスレッドローカルストレージを合わせて利用する場合は注意が必要である。

なおC++標準規格ではC++11以降一貫して、「launch::asyncを指定して本関数を呼び出した場合は新しいスレッドを起動する」という様に記述されているため、MSVCのこの実装は規格違反となる。

例

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

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

処理系

  • Clang: 9.0.1 ✅
  • GCC: 4.7.0 ✅
  • Visual C++: 2012 ✅

参照

  • LWG Issue 2021. Further incorrect usages of result_of
    • C++14で、戻り値型の計算にdecayを適用するようにした。
  • LWG Issue 2120. What should async do if neither async nor deferred is set in policy?
  • async関数launch::asyncポリシーとfutureのちょっと特殊な動作 - yohhoyの日記
  • P0604R0 Resolving GB 55, US 84, US 85, US 86
  • P0600R1 [[nodiscard]] in the Library, Rev1
    • C++20で[[nodiscard]]が付加された
  • In Visual Studio, thread_local variables' destructor not called when used with std::async, is this a bug? - stackoverflow
  • <future> functions - Microsoft Docs
  • P2422R1 Remove nodiscard annotations from the standard library specification
    • C++26で[[nodiscard]]指定が削除された
  • LWG Issue 2186. Incomplete action on async/launch::deferred
    • C++14で、launch::deferredで遅延実行した場合にも、戻り値と送出された例外が共有状態へ格納されることが規定された
    • この修正は欠陥報告(DR)であり、C++11以降に遡及して適用される。launch::async側にのみ規定があり遅延実行の結果をどう扱うかが規定から抜けていた記載漏れの補完であり、処理系は当初から現在の動作を採っていたため
  • LWG Issue 2752. Throws: clauses of async and packaged_task are unimplementable
    • 実装上必要な内部確保を反映し、asyncがbad_allocも送出しうることが規定された
    • この修正は欠陥報告(DR)であり、C++11以降に遡及して適用される。型消去のための内部確保が必要なため元のThrows節は実装不可能であり、処理系は当初からbad_allocを送出しえたため
  • LWG Issue 3476. thread and jthread constructors require that the parameters be move-constructible
    • C++23で、is_constructible要件が既に目的を満たすため、冗長だったムーブ構築可能(is_move_constructible)の要件が削除された
You are visitor 01402503 — GeezerVison does not store the pages you look up.
Best viewed with Netscape Navigator 4.7 or Internet Explorer 6 at 800×600. No cookies required.