最終更新日時(UTC):
が更新

履歴 編集

function
<thread>

std::jthread::コンストラクタ(C++20)

jthread() noexcept;                      // (1) C++20

template <class F, class... Args>
explicit jthread(F&& f, Args&&... args); // (2) C++20

jthread(const jthread&) = delete;        // (3) C++20

jthread(jthread&&) noexcept;             // (4) C++20

概要

  • (1) : デフォルトコンストラクタ。新しいスレッドを生成せず、空の状態にする。
  • (2) : 新しいスレッドを生成し、そのスレッド上で引数args...を渡して、関数オブジェクトfを呼び出す。
  • (3) : コピーコンストラクタ。コピー不可。
  • (4) : ムーブコンストラクタ。スレッドの所有権を移動する。

テンプレートパラメータ制約

  • (2) :

適格要件

効果

同期

  • (2) : コンストラクタ呼び出しの完了は、fのコピーの呼び出し開始と同期する

新しいスレッドを生成し、INVOKE(DECAY_COPY(std::forward<F>(f)), DECAY_COPY(std::forward<Args>(args))...)を実行する。ただしDECAY_COPYは同コンストラクタを呼び出したスレッド上にて評価される。またfのコピーの戻り値は無視される。 - DECAY_COPY(x)template <class T> typename std::decay<T>::type decay_copy(T&& v) { return std::forward<T>(v); } と定義される。おおよそ、xが配列型なら先頭要素へのポインタ、xが関数型ならその関数ポインタ、xがコピーコンストラクト可能な型ならxからコピーされたオブジェクト、xがムーブコンストラクト可能な型ならxからムーブされたオブジェクトとなる。

同期

  • (2) : 同コンストラクタの呼び出し完了は、fのコピーの呼び出し開始と同期する。つまり、「コンストラクタ呼び出し側スレッドT0でのコンストラクタ呼び出し完了」は、「新しいスレッドT1上でのfのコピーの呼び出し開始」よりも前に発生する

事後条件

例外

  • (2) : 新しいスレッドの作成に失敗した場合、system_error例外を投げる。その例外オブジェクトには、以下のエラー状態が設定されうる:

    • resource_unavailable_try_again : 新たなスレッドを作るためのリソースが不足している。もしくはシステムやプロセスが規定するスレッド数の上限を超過した。

#include <iostream>
#include <cstdint>
#include <thread>

std::uint64_t sum1 = 0;
std::uint64_t sum2 = 0;

void f1(std::stop_token stoken, std::uint64_t n)
{
  sum1 = 0;
  for (std::uint64_t i = 1; i < n; ++i) {
    if (stoken.stop_requested()) {
      // 中断リクエストがきたのでスレッドを終了する
      break;
    }
    sum1 += i;
  }
}

void f2(std::uint64_t n)
{
  sum2 = 0;
  for (std::uint64_t i = 1; i < n; ++i) {
    sum2 += i;
  }
}

int main()
{
  {
    // 関数の第1引数がstd::stop_token型である場合、
    // スレッドに中断リクエストを送れるようになる
    std::jthread t1 {f1, 1'000'000};
    std::this_thread::sleep_for(std::chrono::milliseconds{3});
    t1.request_stop(); // スレッドの中断要求を発行

    // スレッド実行する関数がstd::stop_tokenを受け取らない場合、
    // 中断リクエストを使用せず、
    // デストラクタで自動的にjoinするスレッドオブジェクトとして使用する
    std::jthread t2 {
      [] { f2(1'000'000); }
    };
  } // jthreadのデストラクタでは、中断要求を発行し、スレッドの終了を待機する

  std::cout << sum1 << std::endl; // 計算できたところまで表示
  std::cout << sum2 << std::endl;
}

出力例

48458670270
499999500000

バージョン

言語

  • C++20

処理系