初めに†
- C++11 では thread がサポートされている。→ std::thread class を使う
- gcc では build 時に -pthread オプションを要求される場合がある
thread の作成†
- 関数や関数オブジェクトの呼び出し演算子が仮引数を取る場合、 std::thread のコンストラクタの第2引数以降に関数や関数オブジェクトの関数呼び出し演算子へ与える実引数を渡す。
- std::thread のコンストラクタに渡された実引数は、受け取る関数が参照渡しとして宣言されていたとしても、コピーされて std::thread クラスのオブジェクト内に保存される。
- 上記コピーを避けたい場合は、実引数をムーブするか、 std::ref() 関数でくるんで渡す。
- std::ref() を使用した場合、作成した thread に参照が渡されるので、元のオブジェクトの寿命に注意すること。
- thread 内で例外が発生し、 catch されないまま thread 外に送出されると、std::terminate() が呼び出され、プログラムが強制終了する。
thread 終了を待機する†
thread を手放す†
thread の識別†
- std::thread::id std::thread::get_id() を呼ぶ
void foo( ostringstream &os ) {
os << "foo(): " << this_thread::get_id() << endl;
}
void bar( ostringstream &os ) {
os << "bar(): " << this_thread::get_id() << endl;
}
ostringstream os_foo;
ostringstream os_bar;
thread th1( foo(), ref( os_foo ) );
thread th2( bar(), ref( os_bar ) );
// それぞれの thread ID を得る
thread::id id1 = th1.get_id();
thread::id id2 = th2.get_id();
thread::id id3 = this_thread::get_id();
assert( id1 != is2 );
assert( id1 != is3 );
assert( id2 != is3 );
th1.join();
th2.join();
cout << os_foo.str();
cout << os_bar.str();
cout << "main thread : " << this_thread::get_id() << endl;
現在の thread の処理を明け渡す†
void std::yield() noexcept;
現在の thread をスリープする†
並行実行できる thread の数を取得する†
thread を排他制御する†
リソースのロックを管理する†
複数のリソースをロックする†
ロックせずに吐いたアクセスする†
スレッドセーフに1度だけ関数を呼び出す†
条件変数を使用する†
thread をまたいで値や例外を受け渡す†
非同期処理をする†
スレッドローカル変数を使用する†