🐶
C++ std::threadの使い方
はじめに
C++11から追加されているstd::thread
に関する情報について、全てがまとまっているサイトを見つけられなかったため、ここにまとめることにしました。
std::threadのAPI一覧
Unix系のpthreadを比べるととてもシンプルというか何も出来ないthreadという印象です。
API | 用途 |
---|---|
join | スレッド動作完了待ち、スレッドの開放 |
detach | スレッドを生成したプロセスの管理対象から外す (スレッドを生成したプロセスが終了してもdetachされたスレッドはterminateされずに最後まで動き続ける) |
get_id | スレッド固有のIDを取得 |
hardware_concurrency | H/WでサポートされているCPUスレッド数を取得 |
joinable | コンテキストがスレッドと関連付けられているならtrue、そうでなければfalseを返す |
native_handle | プラットフォーム依存のスレッドハンドルを取得 (Unix系はpthread_t, WindowsはHANDLEのインスタンスを返す) |
swap | std::threadをスワップ |
基本的な使い方
std::thread
のivar (インスタンス変数) 宣言時の第一引数には、スレッド実行するメソッドを指定し、第二引数以降にはスレッド実行対象のメソッドの引数を指定します (メソッドに引数がなければ何も指定しない) 。
std::thread
はivarを生成した時点でスレッド動作開始し、join()
メソッドでそのスレッドが終了するまでそのコンテキスト (以下のサンプルプログラムだとmain関数のプロセス) が待ちに入り、スレッド動作後にスレッドコンテキストの開放を行います。スレッド生成および動作後には、必ず生成したコンテキストでjoin()
をコールすることを忘れないようにして下さい。通常のプログラミングでは基本的にdetach
を利用することはないと思います。
よく忘れがちですが、コンパイル時には-pthread
オプションをお忘れなく。
#include <iostream>
#include <thread>
void ThreadFunc(int num) {
std::cout << "ThreadFunc " << num << std::endl;
}
int main() {
std::thread th1(ThreadFunc, 1);
th1.join();
auto func = [](std::string message) {
std::cout << "thread id = " << std::this_thread::get_id()
<< " " << message << std::endl;
};
std::thread th2(func, "Hellow, World!");
std::cout << "th2's id = " << th2.get_id() << std::endl;
return 0;
}
実行結果
ThreadFunc 1
th2's id = 0x700009cef000
thread id = 0x700009cef000 Hellow, World!
Tips
スレッドの優先度設定
std::threadではスレッドに対する詳細設定が出来ませんので、native_handle()
でプラットフォーム固有のスレッドハンドラを取得し、そのプラットフォームに合わせた形で設定する必要があります。ここではUnix系 (Linux, macOS) の例を以下に示します。
int main() {
auto func = [](std::string message) {
std::cout << "thread id = " << std::this_thread::get_id()
<< " " << message << std::endl;
};
std::thread th2(func, "Hellow, World!");
// 優先度を設定
struct sched_param param;
param.sched_priority = 0;
if (pthread_setschedparam(th2.native_handle(), SCHED_OTHER, ¶m) != 0)
std::cout << "Priority set Error" << std::endl;
th2.join();
return 0;
}
pthread_setschedparamについての参考文献
H/WでサポートされているCPUスレッド数を調べる
int main() {
std::cout << "concurrency = " << std::thread::hardware_concurrency()
<< std::endl;
return 0;
}
実行結果
concurrency = 6
Discussion