C++ 標準ライブラリ<future>
C++11 では<future><future> ヘッダーファイルをインクルードします。これは非同期プログラミングの仕組みを提供し、プログラムが操作の完了を待つ間に他のタスクを実行し続けることを可能にします。<future>このライブラリは C++ 標準ライブラリの並行プログラミングの一部であり、プログラマーがより簡潔かつ安全な方法で非同期操作を処理できるようにします。
<future>このライブラリには、いくつかの重要な型が定義されています:
std::future:非同期操作の結果を表し、操作の状態を照会したり、結果を取得したり、操作の完了を待ったりすることができます。std::promise:~とstd::futureペアにし、非同期操作の結果を設定するために使用されます。std::packaged_task:関数または呼び出し可能なオブジェクトをカプセル化し、それを非同期タスクとして実行できるようにします。
std::promise
std::promise非同期操作の結果を設定するために使用されます。これはstd::futureとペアにして使用されます。
例
#include <iostream>
#include <future>
int main() {
std::promise<int> prom;
std::future<int> fut = prom.get_future();
// 別のスレッドで結果を設定します
std::thread t([prom]() {
prom.set_value(10);
});
// 結果を待ちます
std::cout << "Future value: " << fut.get() << std::endl;
t.join();
return 0;
}
#include <future>
int main() {
std::promise<int> prom;
std::future<int> fut = prom.get_future();
// 別のスレッドで結果を設定します
std::thread t([prom]() {
prom.set_value(10);
});
// 結果を待ちます
std::cout << "Future value: " << fut.get() << std::endl;
t.join();
return 0;
}
出力結果:
Future value: 10
std::packaged_task
std::packaged_task関数または呼び出し可能なオブジェクトをカプセル化し、それを非同期タスクとして実行できるようにします。
例
#include <iostream>
#include <future>
#include <cmath>
int compute_square_root(double x) {
return std::sqrt(x);
}
int main() {
std::packaged_task<double(double)> task(compute_square_root);
std::future<double> result = task.get_future();
std::thread th(std::move(task), 9.0);
std::cout << "Result: " << result.get() << std::endl;
th.join();
return 0;
}
#include <future>
#include <cmath>
int compute_square_root(double x) {
return std::sqrt(x);
}
int main() {
std::packaged_task<double(double)> task(compute_square_root);
std::future<double> result = task.get_future();
std::thread th(std::move(task), 9.0);
std::cout << "Result: " << result.get() << std::endl;
th.join();
return 0;
}
出力結果:
Result: 3
std::async
std::async非同期タスクを開始するための便利な関数です。これは即座にstd::futureオブジェクトを返すことができます。
例
#include <iostream>
#include <future>
int main() {
std::future<int> fut = std::async(std::launch::async, [](int x) {
return x * x;
}, 5);
std::cout << "Result: " << fut.get() << std::endl;
return 0;
}
#include <future>
int main() {
std::future<int> fut = std::async(std::launch::async, [](int x) {
return x * x;
}, 5);
std::cout << "Result: " << fut.get() << std::endl;
return 0;
}
出力結果:
Result: 25
例外処理
非同期操作が例外をスローした場合、std::futureこの例外をキャッチし、.get()メソッドを呼び出すことで、それを再スローできます。
例
#include <iostream>
#include <future>
void throw_exception() {
throw std::runtime_error("Exception thrown");
}
int main() {
std::future<void> fut = std::async(throw_exception);
try {
fut.get();
} catch (const std::exception& e) {
std::cout << "Caught exception: " << e.what() << std::endl;
}
return 0;
}
#include <future>
void throw_exception() {
throw std::runtime_error("Exception thrown");
}
int main() {
std::future<void> fut = std::async(throw_exception);
try {
fut.get();
} catch (const std::exception& e) {
std::cout << "Caught exception: " << e.what() << std::endl;
}
return 0;
}
出力結果:
Caught exception: Exception thrown
<future>このライブラリは C++ プログラマーに、シンプルかつ強力な非同期プログラミングの方法を提供します。std::promise、std::packaged_taskとstd::asyncを使用することで、C++ プログラムで並行処理と非同期操作を簡単に実装できます。同時に、例外処理の仕組みはプログラムの堅牢性も保証します。