std::jthread::request_stop
| bool request_stop() noexcept; |
(seit C++20) | |
Löst eine Stopp-Anforderung für den internen Stop-Zustand aus, falls nicht bereits eine Stopp-Anforderung gestellt wurde.
Die Bestimmung erfolgt atomar, und wenn ein Stopp angefordert wurde, wird der Stop-Zustand atomar aktualisiert, um Wettlaufsituationen zu vermeiden, sodass
- stop_requested() und stop_possible() gleichzeitig auf anderen std::stop_tokens und std::stop_sources desselben gemeinsamen Stop-Zustands aufgerufen werden können.
- request_stop() kann gleichzeitig von mehreren Threads auf demselben
jthread-Objekt oder auf anderen std::stop_source-Objekten, die mit demselben Stop-Zustand verbunden sind, aufgerufen werden, und nur einer wird tatsächlich die Stopp-Anforderung ausführen.
Siehe jedoch den Abschnitt Hinweise.
Inhalt |
[bearbeiten] Parameter
(keine)
[bearbeiten] Rückgabewert
true, wenn dieser Aufruf eine Stopp-Anforderung gestellt hat, andernfalls false.
[bearbeiten] Nachbedingungen
Für ein std::stop_token, das durch get_stop_token() abgerufen wird, oder eine std::stop_source, die durch get_stop_source) abgerufen wird, ist stop_requested() true.
[bearbeiten] Hinweise
Wenn request_stop() tatsächlich eine Stopp-Anforderung auslöst (d.h. true zurückgibt), dann werden alle std::stop_callbacks, die für denselben zugehörigen Stop-Zustand registriert wurden, synchron auf demselben Thread aufgerufen, auf dem request_stop() aufgerufen wird. Wenn ein Aufruf eines Callbacks über eine Ausnahme beendet wird, wird std::terminate aufgerufen.
Wenn bereits eine Stopp-Anforderung gestellt wurde, gibt diese Funktion false zurück. Es gibt jedoch keine Garantie, dass ein anderer Thread oder ein std::stop_source-Objekt, das gerade (erfolgreich) einen Stopp für denselben Stop-Zustand angefordert hat, nicht noch mitten im Aufruf einer std::stop_callback-Funktion steckt.
Wenn request_stop) eine Stopp-Anforderung auslöst (d.h. true zurückgibt), dann werden alle Bedingungsvariablen vom Basistyp std::condition_variable_any, die mit einem unterbrechbaren Warten auf std::stop_tokens, die mit dem internen Stop-Zustand des jthreads verbunden sind, registriert wurden, geweckt.
[bearbeiten] Beispiel
#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. }
Mögliche Ausgabe
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