std::asyncめも
std::asyncなるものがあると聞いたので、とりあえずどんな感じで使えばいいのかをめも。
まずはこちらから。
#include <iostream> #include <thread> #include <future> #include <chrono> using namespace std; class Hoge{ public: Hoge(){ cout << "Hoge::Hoge()" << endl; } ~Hoge(){ cout << "Hoge::~Hoge()" << endl; } void operator()(){ cout << "thread start" << endl; this_thread::sleep_for(chrono::seconds(5)); cout << "thread end" << endl; } }; int main(int argc, char **argv){ Hoge hoge; async(launch::async, ref(hoge)); //これはスレッドの終了を待つ cout << "---" << endl; auto f = async(launch::async, ref(hoge)); //これはfのデストラクタでスレッドの終了を待つ cout << "main end" << endl; //f.wait(); return 0; }
実行結果
$ ./a.exe Hoge::Hoge() thread start thread end
-
- -
使い方は、asyncに実行したい関数オブジェクトを渡すだけ。
async(launch::async, ref(hoge));
のように、戻り値を受け取らないように書いた場合は、そこでスレッドの終了を待つみたい。
auto f = async(launch::async, ref(hoge));
のように、戻り値(型はstd::futureになるみたい)を受け取った場合は、std::future::wait()などが用意されてるので、それを使えばスレッドの終了待ちができるみたい。
今回はwait()使ってないけど、fのデストラクタで終了待ちしてくれるみたいでした。
また、スレッドで投げた例外を受け取りたい場合、std::future::get();を使えばいいみたい。
#include <iostream> #include <thread> #include <future> #include <chrono> using namespace std; class Hoge{ public: Hoge(){ cout << "Hoge::Hoge()" << endl; } ~Hoge(){ cout << "Hoge::~Hoge()" << endl; } void operator()(){ cout << "thread start" << endl; this_thread::sleep_for(chrono::seconds(5)); throw 999; cout << "thread end" << endl; } }; int main(int argc, char **argv){ try{ Hoge hoge; auto f = async(launch::async, ref(hoge)); cout << "---" << endl; f.get(); cout << "---" << endl; }catch(int i){ cout << i << endl; } cout << "main end" << endl; return 0; }
実行結果
$ ./a.exe Hoge::Hoge()
-
- -
f.get();ってやってるところで、例外を受け取ってます。
すると、catch節にいくので、次のcout << "---" << endl;は呼ばれません。
get()は例外の他に、returnの値も受け取ることができるらしいです。
なんかスレッド周りの話が続いてるけど、スレッドおっ立てるのが趣味って訳じゃないです。
今日のめもおしまい。