Namespaces
Variants

std::jthread:: request_stop

From cppreference.net
Concurrency support library
Threads
(C++11)
(C++20)
this_thread namespace
(C++11)
(C++11)
Cooperative cancellation
Mutual exclusion
Generic lock management
Condition variables
(C++11)
Semaphores
Latches and Barriers
(C++20)
(C++20)
Futures
(C++11)
(C++11)
(C++11)
Safe reclamation
Hazard pointers
Atomic types
(C++11)
(C++20)
Initialization of atomic types
(C++11) (deprecated in C++20)
(C++11) (deprecated in C++20)
Memory ordering
(C++11) (deprecated in C++26)
Free functions for atomic operations
Free functions for atomic flags
bool request_stop ( ) noexcept ;
(C++20以降)

内部の停止状態に対して停止要求がまだ行われていない場合、停止要求を発行します。

決定は原子的に行われ、停止が要求された場合、競合状態を回避するために停止状態が原子的に更新されます。具体的には:

  • stop_requested ( ) および stop_possible ( ) は、同じ共有停止状態を持つ他の std::stop_token および std::stop_source に対して並行して呼び出すことができます。
  • request_stop ( ) は、同じ jthread オブジェクト、または同じ停止状態に関連付けられた他の std::stop_source オブジェクトに対して、複数のスレッドから並行して呼び出すことができ、実際に停止要求を実行するのは1つだけです。

ただし、「注意」セクションを参照してください。

目次

パラメータ

(なし)

戻り値

true この呼び出しが停止要求を行った場合、それ以外の場合は false

事後条件

std::stop_token によって取得された、または std::stop_source によって取得された場合、 get_stop_token ( ) または get_stop_source ( ) によって取得された stop_requested ( ) true となります。

注記

request_stop ( ) が停止要求を発行する場合(つまり true を返す場合)、同じ関連付けられた停止状態に対して登録された std::stop_callbacks はすべて同期的に、 request_stop ( ) が発行されたのと同じスレッドで呼び出されます。コールバックの呼び出しが例外によって終了した場合、 std::terminate が呼び出されます。

停止要求が既に行われている場合、この関数は false を返します。ただし、同じ停止状態に対して停止を(正常に)要求した別のスレッドや std::stop_source オブジェクトが、まだ std::stop_callback 関数の呼び出しの途中である可能性は排除されません。

request_stop ( ) が停止要求を発行する場合(つまり true を返す場合)、基底型 std::condition_variable_any のすべての条件変数で、 std::stop_token に関連付けられた割り込み可能な待機が登録され、 jthread の内部停止状態に関連する条件変数が起床されます。

#include <chrono>
#include <condition_variable>
#include <iostream>
#include <mutex>
#include <thread>
using namespace std::chrono_literals;
// どのスレッドが何を出力したかを素早く表示するヘルパー関数
void print(auto txt)
{
    std::cout << std::this_thread::get_id() << ' ' << txt;
}
int main()
{
    // スリーピーワーカースレッド
    std::jthread sleepy_worker(
        [](std::stop_token stoken)
        {
            for (int i = 10; i; --i)
            {
                std::this_thread::sleep_for(300ms);
                if (stoken.stop_requested())
                {
                    print("Sleepy worker is requested to stop\n");
                    return;
                }
                print("Sleepy worker goes back to sleep\n");
            }
        });
    // ウェイティングワーカースレッド
    // 条件変数は停止要求によって起動されます
    std::jthread waiting_worker(
        [](std::stop_token stoken)
        {
            std::mutex mutex;
            std::unique_lock lock(mutex);
            std::condition_variable_any().wait(lock, stoken, []{ return false; });
            print("Waiting worker is requested to stop\n");
            return;
        });
    // スレッドに回転する時間を与えるためにこのスレッドをスリープ
    std::this_thread::sleep_for(400ms);
    // std::jthread::request_stop() は明示的に呼び出せます:
    print("Requesting stop of sleepy worker\n");
    sleepy_worker.request_stop();
    sleepy_worker.join();
    print("Sleepy worker joined\n");
    // またはRAIIを使用して自動的に:
    // waiting_workerのデストラクタはrequest_stop()を呼び出し
    // スレッドを自動的にjoinします
}

出力例:

140287602706176 Sleepy worker goes back to sleep
140287623300928 Requesting stop of sleepy worker
140287602706176 Sleepy worker is requested to stop
140287623300928 Sleepy worker joined
140287594313472 Waiting worker is requested to stop