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

履歴 編集

function
<stop_token>

std::stop_source::request_stop(C++20)

bool request_stop() noexcept;

概要

自身が所有している停止状態に対して停止要求を作成する。

効果

自身が停止状態を所有していない場合は何もせずfalseを返す。

それ以外の場合は、自身の所有している停止状態が停止要求を受け取っているかどうかをアトミックに判定し、まだ停止要求を受け取っていない場合は停止要求を作成する。
この判定処理と停止要求の作成処理は、read-modify-write操作によってアトミックに行われる。
停止要求を受け取っていると判定した場合は何もせずfalseを返す。

停止要求が作成されたときは、この停止状態に対して登録されているstop_callbackのコールバックが同期的に呼び出される。このコールバックの呼び出しが例外によって終了した場合は、std::terminate()関数が呼び出され、プログラムが異常終了する。

もし停止要求が作成されたときに、割り込み可能な待機関数(wait()wait_for()wait_until())で待機中のcondition_variable_anyが存在している場合は、そのようなcondition_variable_any全てに対して起床通知が送られ、待機関数から処理が戻る。

戻り値

この関数の呼び出しによって停止要求が作成された場合はtrueを返す。

停止状態を所有していない、あるいは停止要求がすでに作成されていた場合はfalseを返す。

例外

投げない。

#include <cassert>
#include <stop_token>
#include <condition_variable>
#include <mutex>
#include <thread>

int main()
{
  {
    std::stop_source ss1;
    std::stop_source ss2(std::nostopstate);

    assert(ss1.request_stop() == true);

    // 二度目以降の停止要求は効果を持たない
    assert(ss1.request_stop() == false);

    // 停止状態を所有していない stop_source に対しては
    // 停止要求を作成できない
    assert(ss2.request_stop() == false);
  }

  {
    std::stop_source ss;

    // コールバックを登録
    bool b1 = false;
    std::stop_callback cb1 { ss.get_token(), [&] { b1 = true; } };

    // コールバックを登録
    bool b2 = false;
    std::stop_callback cb2 { ss.get_token(), [&] { b2 = true; } };

    assert(b1 == false && b2 == false);

    // この中で、 ss が所有している停止状態に対して登録されている
    // すべてのコールバックが呼び出される
    ss.request_stop();

    assert(b1 == true && b2 == true);
  }

  {
    std::stop_source ss;
    std::mutex mtx;

    auto cv_wait_test_func = [&] {
      // 待機を終了するための条件を表す述語。
      // この述語は常に false を返すため、永久に待機し続けることを意味する。
      auto wait_forever = [] { return false; };

      std::condition_variable_any cv;
      std::unique_lock lock { mtx };

      // 割り込み可能な待機処理を行う。
      // 割り込み可能な待機関数は、停止要求によって起床通知が送られたときに、
      // 述語が返す値に関わらず待機関数から処理を戻す。
      cv.wait(lock, ss.get_token(), wait_forever);
    };

    std::thread t1(cv_wait_test_func);
    std::thread t2(cv_wait_test_func);

    std::this_thread::sleep_for(std::chrono::milliseconds(100));

    // 停止要求を作成すると、ss が所有する停止状態を利用して割り込み可能な待機処理を行っている
    // すべての condition_variable_any に対して、起床通知が送られる。
    ss.request_stop();

    t1.join();
    t2.join();
  }
}

出力

バージョン

言語

  • C++20

処理系