- こちらと併せてご覧ください:「スレッド・ライブラリひとめぐり」
スレッドを起動する
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() : 親権放棄 すべし }