- こちらと併せてご覧ください:「スレッド・ライブラリひとめぐり」
スレッドを起動する
std::threadを用いたスレッドの生成はpthread_create()やCreateThread()より数十倍(当社比)簡単、関数オブジェクトとそれに渡す引数とをstd::threadのコンストラクタに与えるだけでスレッドが生成され、そのスレッドの中で関数オブジェクトが動き始めます。
#include <thread>
#include <chrono>
#include <string>
#include <iostream>
/*
* フツーの関数
*/
void global_fun(int n) {
using namespace std;
cout << "global_fun: " + to_string(n) + " 秒後に終了します...\n";
this_thread::sleep_for(chrono::seconds(n));
cout << "global_fun: おしまい\n";
}
/*
* ラムダ式
*/
auto lambda_exp = [](int n) {
using namespace std;
cout << "lambda_exp: " + to_string(n) + " 秒後に終了します...\n";
this_thread::sleep_for(chrono::seconds(n));
cout << "lambda_exp: おしまい\n";
};
/*
* メンバ関数
*/
#include <functional>
class Foo {
private:
int bias_;
public:
explicit Foo(int b) : bias_(b) {}
void member_fun(int n) {
using namespace std;
cout << "member_fun: " + to_string(bias_+n) + " 秒後に終了します...\n";
this_thread::sleep_for(chrono::seconds(bias_+n));
cout << "member_fun: おしまい\n";
}
// 関数オブジェクトを返す wrapper
std::function<void(int)> member_fun() {
// this をキャプチャした lambda で wrap する
return [this](int n) { member_fun(n); };
}
};
// おためし
int main() {
using namespace std;
cout << "いろんなタスクからスレッドを作るよ!\n";
thread thr0(global_fun, 2);
thread thr1(lambda_exp, 3);
Foo foo(3);
thread thr2(foo.member_fun(), 1);
cout << "スレッドの終了を待ってます\n";
thr0.join();
thr1.join();
thr2.join();
cout << "ぜんぶおしまい\n";
}

スレッド終了より先にstd::threadがデストラクトされるとstd::terminate()により異常終了しちゃうので、必ずjoin()でスレッドの終了を待つか、あるいはdetach()でスレッドをstd::threadの管理下から外しておきましょう。
#include <thread>
#include <chrono>
#include <string>
#include <iostream>
#include <exception>
void bad_termination() {
std::cerr << "異常終了!!\n";
}
int main() {
using namespace std;
std::set_terminate(bad_termination);
cout << "main:\n";
thread thr([](int n) {
cout << "lambda_exp: " + to_string(n) + " 秒後に終了します...\n";
this_thread::sleep_for(chrono::seconds(n));
cout << "lambda_exp: おしまい\n";
}, 2);
cout << "main:おしまい\n";
// 異常終了を避けたいなら thr.join() : 完了待ち
// さもなくば thr.detach() : 親権放棄 すべし
}

