Namespaces
Variants

std:: async

From cppreference.net
Concurrency support library
Threads
(C++11)
(C++20)
this_thread namespace
(C++11)
(C++11)
Cooperative cancellation
Mutual exclusion
Generic lock management
Condition variables
(C++11)
Semaphores
Latches and Barriers
(C++20)
(C++20)
Futures
(C++11)
(C++11)
async
(C++11)
Safe reclamation
Hazard pointers
Atomic types
(C++11)
(C++20)
Initialization of atomic types
(C++11) (deprecated in C++20)
(C++11) (deprecated in C++20)
Memory ordering
(C++11) (deprecated in C++26)
Free functions for atomic operations
Free functions for atomic flags
ヘッダーで定義 <future>
template < class F, class ... Args >
std:: future < /* 詳細は後述 */ > async ( F && f, Args && ... args ) ;
(1) (C++11以降)
template < class F, class ... Args >

std:: future < /* 詳細は後述 */ > async ( std:: launch policy,

F && f, Args && ... args ) ;
(2) (C++11以降)

関数テンプレート std::async は関数 f を非同期に(別スレッドで、スレッドプールの一部である可能性もある)実行し、その関数呼び出しの結果を最終的に保持する std::future を返します。

1) (2) policy std:: launch :: async | std:: launch :: deferred が指定された状態で呼び出されたかのように振る舞う。
2) 特定の起動ポリシー policy に従って( 下記 参照)、引数 args を用いて関数 f を呼び出します。

std::async の戻り値の型は std:: future < V > であり、ここで V は以下を指します:

typename std:: result_of < typename std:: decay < F > :: type (
typename std:: decay < Args > :: type ... ) > :: type .

(C++17まで)

std:: invoke_result_t < std:: decay_t < F > , std:: decay_t < Args > ... > .

(C++17から)


以下のいずれかの条件が満たされる場合、プログラムは不適格となる:

(C++20以前)

以下のいずれかが false の場合、プログラムは不適格となる:

(C++20以降)

std::async への呼び出しは、 同期する f への呼び出しと、そして f の完了は共有状態の準備完了より 前に順序付けられる

目次

翻訳の説明: - 「Contents」を「目次」に翻訳しました - C++関連の専門用語(Parameters、Return value、Launch policies、Async invocation、Deferred invocation、Exceptionsなど)は原文のまま保持しました - HTMLタグ、属性、class名、IDなどは一切変更していません - 番号付けや構造は完全に保持されています - 技術文書としての正確性と専門性を維持しています

パラメータ

f - Callable を呼び出すオブジェクト
args - f に渡すパラメータ
policy - 個々のビットが実行を許可する方法を制御するビットマスク値

戻り値

std::future が、この std::async の呼び出しによって作成された共有状態を参照します。

起動ポリシー

非同期呼び出し

async フラグが設定されている場合、すなわち ( policy & std:: launch :: async ) ! = 0 の場合、 std::async は呼び出しを行います

INVOKE ( decay-copy ( std:: forward < F > ( f ) ) ,
decay-copy ( std:: forward < Args > ( args ) ) ... )

(C++23まで)

std:: invoke ( auto ( std:: forward < F > ( f ) ) ,
auto ( std:: forward < Args > ( args ) ) ... )

(C++23から)

あたかも std::thread オブジェクトによって表される新しい実行スレッド内であるかのように。

decay-copy の呼び出しは現在のスレッドで評価される。

(C++23まで)

auto によって生成される値は現在のスレッドで 実体化 される。

(C++23以降)

関数 f が値を返すか例外をスローする場合、その結果は std::future を通じてアクセス可能な共有状態に格納されます。この std::async は呼び出し元に返されます。

遅延呼び出し

deferred フラグが設定されている場合(すなわち ( policy & std:: launch :: deferred ) ! = 0 )、 std::async は保存します

decay-copy ( std:: forward < F > ( f ) ) および decay-copy ( std:: forward < Args > ( args ) ) ... を共有状態に格納する。

(C++23まで)

auto ( std:: forward < F > ( f ) ) および auto ( std:: forward < Args > ( args ) ) ... を共有状態に格納する。

(C++23から)

遅延評価 が実行されます:

  • 非タイムド待機関数の最初の呼び出しが、 std::future に対して行われる場合、 std::async が呼び出し元に返したものは、 INVOKE ( std :: move ( g ) , std :: move ( xyz ) ) を待機関数を呼び出したスレッド(元々 std::async を呼び出したスレッドである必要はない)で評価する。ここで
(C++23まで)
  • g auto ( std:: forward < F > ( f ) ) の格納された値であり、
  • xyz auto ( std:: forward < Args > ( args ) ) ... の格納されたコピーである。
(C++23以降)
  • 結果または例外は、返された std::future に関連付けられた共有状態に配置され、その後初めて準備完了状態となります。同じ std::future への以降のすべてのアクセスは、即座に結果を返します。

その他のポリシー

std::launch::async std::launch::deferred も、あるいは実装定義のポリシーフラグも policy に設定されていない場合、動作は未定義です。

ポリシー選択

複数のフラグが設定されている場合、どのポリシーが選択されるかは実装定義です。デフォルト( std::launch::async std::launch::deferred の両方のフラグが policy に設定されている場合)については、標準では利用可能な並行性を活用し、追加のタスクを延期することを推奨(ただし必須ではない)しています。

std::launch::async ポリシーが選択された場合、

  • この std::async 呼び出しによって作成された共有状態を共有する非同期戻りオブジェクトに対する待機関数の呼び出しは、関連するスレッドが完了する(joinされたかのように)か、タイムアウトするまでブロックする;および
  • 関連するスレッドの完了は、共有状態を待機する最初の関数の成功した戻りと、あるいは共有状態を解放する最後の関数の戻りのいずれか早い方と 同期する

例外

例外送出

注記

実装は、デフォルト起動ポリシーに追加の(実装定義の)ビットを有効にすることで、 std::async の最初のオーバーロードの動作を拡張する場合があります。

実装定義の起動ポリシーの例としては、同期ポリシー( std::async 呼び出し内で即時実行)とタスクポリシー( std::async と同様だが、スレッドローカル変数がクリアされない)がある。

std::future から取得された std::async の結果がムーブされない場合、または参照にバインドされない場合、 std::future のデストラクタは完全式の終了時点で非同期操作が完了するまでブロックします。これは実質的に以下のようなコードを同期処理にすることになります:

std::async(std::launch::async, []{ f(); }); // 一時オブジェクトのデストラクタが f() の完了を待機
std::async(std::launch::async, []{ g(); }); // f() が完了するまで実行が開始されない

std::future のデストラクタは、 std::async の呼び出し以外の手段で取得された場合、決してブロックしないことに注意してください。

#include <algorithm>
#include <future>
#include <iostream>
#include <mutex>
#include <numeric>
#include <string>
#include <vector>
std::mutex m;
struct X
{
    void foo(int i, const std::string& str)
    {
        std::lock_guard<std::mutex> lk(m);
        std::cout << str << ' ' << i << '\n';
    }
    void bar(const std::string& str)
    {
        std::lock_guard<std::mutex> lk(m);
        std::cout << str << '\n';
    }
    int operator()(int i)
    {
        std::lock_guard<std::mutex> lk(m);
        std::cout << i << '\n';
        return i + 10;
    }
};
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';
    X x;
    // デフォルトポリシーで (&x)->foo(42, "Hello") を呼び出し:
    // "Hello 42" を同時に出力するか、実行を延期する可能性があります
    auto a1 = std::async(&X::foo, &x, 42, "Hello");
    // 延期ポリシーで x.bar("world!") を呼び出し
    // a2.get() または a2.wait() が呼び出されたときに "world!" を出力
    auto a2 = std::async(std::launch::deferred, &X::bar, x, "world!");
    // asyncポリシーで X()(43) を呼び出し
    // 同時に "43" を出力
    auto a3 = std::async(std::launch::async, X(), 43);
    a2.wait();                     // "world!" を出力
    std::cout << a3.get() << '\n'; // "53" を出力
} // この時点で a1 が完了していない場合、a1 のデストラクタがここで "Hello 42" を出力

出力例:

The sum is 10000
43
world!
53
Hello 42

不具合報告

以下の動作変更欠陥報告書は、以前に公開されたC++規格に対して遡及的に適用されました。

DR 適用対象 公開時の動作 修正後の動作
LWG 2021 C++11 遅延評価の場合に戻り値型が不正で、
引数の値カテゴリが不明確
戻り値型を修正し、
右辺値が使用されることを明確化
LWG 2078 C++11 std::system_error がスローされるかどうかが不明確
policy std::launch::async 以外の
起動ポリシーを指定する場合)
スローされるのは
policy == std:: launch :: async の場合のみ
LWG 2100 C++11 タイムアウト機能付き待機関数がタイムアウトしない可能性があった
std::launch::async ポリシーが使用される場合)
許可
LWG 2120 C++11 標準または実装定義のポリシーが設定されていない場合の
動作が不明確
この場合の動作は
未定義
LWG 2186 C++11 遅延評価から返される値とスローされる例外の
扱いが不明確
これらは
共有状態に格納される
LWG 2752 C++11 std::async std::bad_alloc をスローしない可能性があった
(内部データ構造のメモリ割り当てに失敗した場合)
スローする
LWG 3476 C++20 (減衰型の) F と引数型が直接的に
ムーブ構築可能であることが要求されていた
これらの要件を削除 [1]
  1. ムーブ構築可能性は既に間接的に std::is_constructible_v によって要求されている。

関連項目

(C++11)
非同期に設定される値を待機する
(クラステンプレート)
C++ documentation for Execution support library