namespace std {
class thread;
}
概要
クラスthread
は、新しい実行のスレッド(thread of execution)(以下、単にスレッドとする)の作成/待機/その他操作を行う機構を提供する。
threadオブジェクトとスレッドとの関係性
thread
オブジェクトとスレッドは1:1の関係で対応づけられるが、両者は同一ではないことに留意。thread
コンストラクタによって新しく作成されたスレッドは、そのthread
オブジェクトに関係付けられる。
thread
コンストラクタでは新しいスレッドを1つ作成し、同コンストラクタを呼び出したスレッドはそのまま後続処理を続ける。一方で、新しいスレッド上ではthread
コンストラクタに与えた関数オブジェクトが呼び出される。つまりプログラム内に複数のスレッドが存在し、並行にそれぞれの処理を行うことが可能な状態となる。なお、複数のスレッドが真に並行実行されるか否かは処理系に依存する。(たとえばDual Core環境で4つのスレッドを作成することはできるが、ハードウェアの制約から同時処理されるのは2スレッド以下に制限される。)
新しいスレッド上で呼び出される関数オブジェクトから例外が送出された場合、std::terminate()
関数が呼び出されてプログラムは終了する。この動作が好ましくないのであれば、同関数オブジェクトから外に例外送出されないことをプログラマが保証しなければならない。
また、デフォルト構築されたthread
オブジェクトは、何も指さない空のthread
オブジェクトとなる。
join操作とdetach操作
thread
オブジェクトとスレッドが関連付けられた状態では、thread
オブジェクトのメンバ関数join()
を介してそのスレッド完了を待機することができる(join操作)。メンバ関数join()
が呼び出された時点でthread
オブジェクトに関連付けられたスレッドがまだ処理継続中だった場合、その対象スレッドが完了するまで呼び出し元スレッドがブロックされる。このjoin操作が終わったthread
オブジェクトは、何も指さない空のthread
オブジェクトとなる。
またthread
オブジェクトのメンバ関数detach()
により、thread
オブジェクトとスレッドの関連付けを切ることもできる(detach操作)。detach操作がなされたスレッドは、それ以後は他スレッドから直接関与することが出来なくなる。またdetach操作が終わったthread
オブジェクトは、何も指さない空のthread
オブジェクトとなる。
thread
オブジェクトを破棄するデストラクタでは、そのthread
オブジェクトが何も指していないことが要件となっている。言い換えると、新しいスレッドを作成したthread
オブジェクトでは、破棄される前にjoin操作またはdetach操作のいずれか一方が必ず行われなければならない。この要件に反した場合、thread
オブジェクトのデストラクタはstd::terminate()
関数を呼び出してプログラム終了する。
メンバ関数
名前 | 説明 | 対応バージョン |
---|---|---|
(constructor) |
コンストラクタ | C++11 |
(destructor) |
デストラクタ | C++11 |
operator= |
代入演算子 | C++11 |
swap |
別のthread と交換する |
C++11 |
joinable |
スレッドに関連付けられているか否かを取得する | C++11 |
join |
スレッドが終了するまで待機する | C++11 |
detach |
スレッドの管理を手放す | C++11 |
get_id |
関連付けられているスレッドのスレッド識別子を取得する | C++11 |
native_handle |
スレッドに関連付けられたネイティブハンドルを取得する[処理系定義] | C++11 |
静的メンバ関数
名前 | 説明 | 対応バージョン |
---|---|---|
hardware_concurrency |
処理系によりサポートされるスレッド並行数を取得する | C++11 |
メンバ型
名前 | 説明 | 対応バージョン |
---|---|---|
id |
スレッド識別子 (class) | C++11 |
native_handle_type |
ネイティブハンドル型 (type-alias)[処理系定義] | C++11 |
非メンバ関数
名前 | 説明 | 対応バージョン |
---|---|---|
swap |
2つのthread オブジェクトを入れ替える |
C++11 |
備考
型native_handle_type
およびメンバ関数native_handle
について、同メンバの存在有無およびその意味は処理系定義となる。
例
#include <cassert>
#include <thread>
int main()
{
int x = 0, y = 0;
std::thread t([&]{ ++x; });
--y;
t.join();
assert(x == 1 && y == -1);
return 0;
}
xxxxxxxxxx
#include <cassert>
#include <thread>
int main()
{
int x = 0, y = 0;
std::thread t([&]{ ++x; });
--y;
t.join();
assert(x == 1 && y == -1);
return 0;
}
出力
バージョン
言語
- C++11
処理系
- Clang: ??
- GCC: 4.7.0 ✅
- ICC: ??
- Visual C++: 2012 ✅, 2013 ✅, 2015 ✅
- 2012はメモリリークするバグあり link