std::jthread:: request_stop
|
|
|||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| Member functions | ||||
| Observers | ||||
| Operations | ||||
| Stop token handling | ||||
|
jthread::request_stop
|
||||
| Non-member functions | ||||
|
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