非同期タスク
以下のコードは、30個のタスクを同時に実行します。各タスクは、一秒間 sleep_for するだけです。
// async1.cpp #include <algorithm> #include <chrono> #include <future> #include <iostream> #include <iterator> #include <thread> #include <vector> using namespace std; int main(int, char *[]) { vector<future<void>> futures; for(auto i = 0; i < 30; i++) { auto src = async([]{this_thread::sleep_for(chrono::seconds(1));}); futures.push_back(move(src)); } for_each(begin(futures), end(futures), [](future<void> & I){ I.wait(); }); cout << "done." << endl; return 0; }
実行すると、一秒で制御を戻します。要約すると、future<void>vectorasync のラムダを30個格納して、wait で各 async の終了を待つだけです。
async について、デフォルト動作であるこのケースでは、生成された時点でタスクが開始されています。async は、future のラッパーなので、future<void> に代入しています。なぜここで void なのかというと、ラムダの返値が void だからです。返値が int なら future<int> になります。その場合の例を以下のコードに示します。
// async2.cpp #include <future> #include <iostream> using namespace std; int ref1() { return 1; } int ref2() { return 2; } int main(int, char *[]) { future<int> f1 = async(ref1); future<int> f2 = async(ref2); int result = f1.get() + f2.get(); cout << "result = " << result << endl; return 0; }
async には関数、ラムダ、ファンクタを渡すことができます。