std::condition_variable_any::wait_for
| template< class Lock, class Rep, class Period > std::cv_status wait_for( Lock& lock, |
(1) | (seit C++11) |
| template< class Lock, class Rep, class Period, class Predicate > bool wait_for( Lock& lock, const std::chrono::duration<Rep, Period>& rel_time, |
(2) | (seit C++11) |
| template< class Lock, class Rep, class Period, class Predicate > bool wait_for( Lock& lock, std::stop_token stoken, |
(3) | (seit C++20) |
wait_for veranlasst den aufrufenden Thread zu blockieren, bis die Bedingungsvariable benachrichtigt wird, die angegebene Dauer abgelaufen ist oder ein unerwarteter Aufwachvorgang (spurious wakeup) auftritt. pred kann optional angegeben werden, um unerwartete Aufwachvorgänge zu erkennen.
std::chrono::steady_clock::now() + rel_time, std::move(pred));.
Unmittelbar nach Rückkehr von wait_for ist lock vom aufrufenden Thread gesperrt. Wenn diese Nachbedingung nicht erfüllt werden kann[1], wird std::terminate aufgerufen.
- ↑ Dies kann passieren, wenn das erneute Sperren des Mutex eine Ausnahme auslöst.
Inhalt |
[bearbeiten] Parameter
| lock | - | ein Lock, der vom aufrufenden Thread gesperrt sein muss |
| stoken | - | ein Stop-Token, um die Unterbrechung dafür zu registrieren |
| rel_time | - | Die maximale Wartezeit |
| pred | - | das Prädikat, um zu überprüfen, ob das Warten abgeschlossen werden kann |
| Typanforderungen | ||
-Lock muss die Anforderungen von BasicLockable erfüllen. | ||
-Predicate muss die Anforderungen an ein FunctionObject erfüllen. | ||
| -pred() muss ein gültiger Ausdruck sein, und sein Typ und seine Wertkategorie müssen die BooleanTestable-Anforderungen erfüllen. | ||
[bearbeiten] Rückgabewert
[bearbeiten] Ausnahmen
[bearbeiten] Hinweise
Auch wenn unter Sperre benachrichtigt, macht Überladung (1) keine Garantien über den Zustand des zugehörigen Prädikats beim Rückkehren aufgrund von Zeitüberschreitung.
Die Effekte von notify_one()/notify_all() und jeder der drei atomaren Teile von wait()/wait_for()/wait_until() (entsperren+warten, aufwecken und sperren) finden in einer einzigen Gesamtordnung statt, die als Modifikationsordnung einer atomaren Variablen betrachtet werden kann: Die Ordnung ist spezifisch für diese einzelne Bedingungsvariable. Dies macht es unmöglich, dass notify_one() beispielsweise verzögert wird und einen Thread aufweckt, der kurz nach dem Aufruf von notify_one() zu warten begonnen hat.
[bearbeiten] Beispiel
#include <chrono> #include <condition_variable> #include <iostream> #include <thread> std::condition_variable_any cv; std::mutex cv_m; // This mutex is used for three purposes: // 1) to synchronize accesses to i // 2) to synchronize accesses to std::cerr // 3) for the condition variable cv int i = 0; void waits() { std::unique_lock<std::mutex> lk(cv_m); std::cerr << "Waiting... \n"; cv.wait(lk, []{ return i == 1; }); std::cerr << "...finished waiting. i == 1\n"; } void signals() { std::this_thread::sleep_for(std::chrono::seconds(1)); { std::lock_guard<std::mutex> lk(cv_m); std::cerr << "Notifying...\n"; } cv.notify_all(); std::this_thread::sleep_for(std::chrono::seconds(1)); { std::lock_guard<std::mutex> lk(cv_m); i = 1; std::cerr << "Notifying again...\n"; } cv.notify_all(); } int main() { std::thread t1(waits), t2(waits), t3(waits), t4(signals); t1.join(); t2.join(); t3.join(); t4.join(); }
Mögliche Ausgabe
Waiting... Waiting... Waiting... Notifying... Notifying again... ...finished waiting. i == 1 ...finished waiting. i == 1 ...finished waiting. i == 1
[bearbeiten] Fehlerberichte
Die folgenden Verhaltensändernden Fehlerberichte wurden rückwirkend auf zuvor veröffentlichte C++-Standards angewendet.
| DR | angewendet auf | Verhalten wie veröffentlicht | Korrigiertes Verhalten |
|---|---|---|---|
| LWG 2093 | C++11 | timeoutbezogene Ausnahmen fehlten in der Spezifikation | erwähnt diese Ausnahmen |
| LWG 2114 (P2167R3) |
C++11 | Konvertierbarkeit in bool war zu schwach, um die Erwartungen der Implementierungen widerzuspiegeln | Anforderungen verstärkt |
| LWG 2135 | C++11 | Das Verhalten war unklar, wenn lock.lock() eine Ausnahme auslöste | in diesem Fall wird std::terminate aufgerufen |
[bearbeiten] Siehe auch
| blockiert den aktuellen Thread, bis die Bedingungsvariable geweckt wird (public member function) | |
| blockiert den aktuellen Thread, bis die Bedingungsvariable geweckt wird oder bis der angegebene Zeitpunkt erreicht ist (public member function) |