深夜開発

プログラミング備忘録

std::threadを使ったスレッド生成

std::thread

C++11より導入された、新しい実行スレッドを生成、待機、その他の操作を行う仕組みを提供するテンプレートクラス。 std::threadのコンストラクタに与えられた関数オブジェクトと、このコンストラクタを呼び出したスレッドとの間で並行に処理が実行される。

コンストラクタの定義は、

template <class F, class ...Args>
explicit thread(F&& f, Args&&... args);

このような可変引数の形になっていて、ラムダ式と共に用いられる場合が多い。

機能は最小限のものしか提供されない為、実装環境に依存したスレッドハンドルを取得するメソッドが提供されており、

native_handle_type native_handle();

このハンドルを使う事で高度なスレッド操作を行うことが出来る。 通常このハンドルは、

  • Unix系環境(libstdc++、libc++)では『pthread_t』
  • MS Windows環境(Visual C++)では『HANDLE』

を表している。 各実装環境でのスレッド生成は以下を参照

kamai-tech-lab.hatenablog.com kamai-tech-lab.hatenablog.com

Sample code

#include <stdio.h>
#include <thread>

int main()
{
    int value = 0;

    // スレッドを作成、発行
    // ここで生成したスレッドの返り値は無視されるため、結果を受け取る変数の参照も渡しておく
    auto mad = std::thread([](int &r, int a, int b, int c)
    {
        r = a * b + c;
    }, std::ref(value), 10, 20, 30);


#ifdef WIN32
    // スレッド優先度を設定
    // 『THREAD_PRIORITY_ABOVE_NORMAL』は通常より1ポイント下の優先順位
    SetThreadPriority(mad.native_handle(), THREAD_PRIORITY_BELOW_NORMAL);
#elif defined(__linux__)
    sched_param param;
    param.sched_priority = 10;

    // スケジューリングポリシー、優先度を設定
    pthread_setschedparam(mad.native_handle(), SCHED_RR, &param);
#endif

    // スレッドが完了するまで待つ
    mad.join();

    // 結果を出力
    printf("value = %d\n", value);
    
    return 0;
}
出力
value = 230