async/future: 非同期プログラミング

別スレッドで計算し、結果を安全に受け取る。

std::future
非同期処理の結果を取得。
std::async
非同期タスクを起動。
std::promise
結果を手動でセット。

非同期処理

ピザの注文 (Ordering Pizza)

非同期処理は「ピザの注文」です。注文(async)すると、レシート(future)を渡されます。ピザが焼ける間、テーブルを拭いたり飲み物を用意したり(他の作業)できます。準備ができたらレシートを見せてピザを受け取ります(get)。ずっとレジの前で待つ必要はありません。

`std::async` は最も手軽にスレッドを扱える関数です。戻り値の `std::future` を通して、処理結果の受け取りや例外の捕捉ができます。スレッドの管理(作成や破棄)をライブラリに任せられるため、`std::thread` よりも安全で推奨されます。

std::async & std::future
#include <future>
// 非同期タスク
std::future<int> fut = std::async(std::launch::async, []() {
std::this_thread::sleep_for(std::chrono::seconds(1));
return 42;
});
// 他の作業...
int result = fut.get(); // ブロックして結果を取得
// タイムアウト付き待機
if (fut.wait_for(std::chrono::milliseconds(500)) == std::future_status::ready) {
result = fut.get();
}
実行結果
(1秒待機)\nfut.get() = 42
Bad
// ❌ Bad: 生スレッド + 共有変数
int result;
std::thread t([&]() { result = compute(); });
t.join(); // 同期が面倒
Good
// ✅ Good: std::async
auto fut = std::async(compute);
int result = fut.get(); // 自動同期

パターン

promise, packaged_task
// std::promise と std::future
std::promise<int> prom;
std::future<int> fut = prom.get_future();
std::thread t([&prom]() {
int result = expensive_computation();
prom.set_value(result); // 結果をセット
});
int value = fut.get(); // 待機して取得
t.join();
// packaged_task
std::packaged_task<int(int, int)> task([](int a, int b) {
return a + b;
});
std::future<int> fut2 = task.get_future();
std::thread(std::move(task), 2, 3).detach();
int sum = fut2.get(); // 5
Tip: シンプルな非同期には std::async。細かい制御には promise/packaged_task。

合格ライン

std::async を使える
future::get で結果を取得できる

参考リンク

演習課題

課題1: async + future
非同期で計算を行い、future::get で結果を取得してください。
課題2: 並列ダウンロード
複数の非同期タスクを起動し、全て完了してからまとめて処理してください。

次のステップ