std::jthread::request_stop
| 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。
[編集] 事後条件
get_stop_token() または get_stop_source() から取得された std::stop_token または std::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 を返した場合)、jthreadの内部停止状態に関連付けられた std::stop_token に対して割り込み可能な待機で登録されている、すべての基底型 std::condition_variable_any の条件変数が再開されます。
[編集] 例
#include <chrono> #include <condition_variable> #include <iostream> #include <mutex> #include <thread> using namespace std::chrono_literals; // Helper function to quickly show which thread printed what void print(auto txt) { std::cout << std::this_thread::get_id() << ' ' << txt; } int main() { // A sleepy worker thread 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"); } }); // A waiting worker thread // The condition variable will be awoken by the stop request. 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; }); // Sleep this thread to give threads time to spin std::this_thread::sleep_for(400ms); // std::jthread::request_stop() can be called explicitly: print("Requesting stop of sleepy worker\n"); sleepy_worker.request_stop(); sleepy_worker.join(); print("Sleepy worker joined\n"); // Or automatically using RAII: // waiting_worker's destructor will call request_stop() // and join the thread automatically. }
実行結果の例
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