std::condition_variable::wait_for
| template< class Rep, class Period > std::cv_status wait_for( std::unique_lock<std::mutex>& lock, |
(1) | (seit C++11) |
| template< class Rep, class Period, class Predicate > bool wait_for( std::unique_lock<std::mutex>& lock, |
(2) | (seit C++11) |
wait_for bewirkt, dass der aktuelle Thread blockiert, bis das condition_variable benachrichtigt wird, die gegebene Dauer abgelaufen ist oder ein fehlerhaftes Aufwachen (spurious wakeup) auftritt. pred kann optional angegeben werden, um fehlerhafte Aufwachvorgänge zu erkennen.
Direkt nach Rückkehr von wait_for ist lock.owns_lock() true und lock.mutex() ist vom aufrufenden Thread gesperrt. Wenn diese Nachbedingungen nicht erfüllt werden können[1], wird std::terminate aufgerufen.
Wenn eine der folgenden Bedingungen erfüllt ist, ist das Verhalten undefiniert
- lock.owns_lock() ist false.
- lock.mutex() ist nicht vom aufrufenden Thread gesperrt.
- Wenn andere Threads auf *this warten, ist lock.mutex() unterschiedlich von dem Mutex, der von den Wartefunktionen (wait,
wait_forund wait_until) freigegeben wird, die auf *this von diesen Threads aufgerufen werden.
- ↑ Dies kann passieren, wenn das erneute Sperren des Mutex eine Ausnahme auslöst.
Inhalt |
[edit] Parameter
| lock | - | Ein Lock, der vom aufrufenden Thread gesperrt sein muss. |
| rel_time | - | Die maximale Wartezeit. |
| pred | - | das Prädikat, um zu überprüfen, ob das Warten abgeschlossen werden kann |
| Typanforderungen | ||
-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. | ||
[edit] Rückgabewert
[edit] Ausnahmen
[edit] Hinweise
Auch wenn unter dem Lock benachrichtigt wird, macht Überladung (1) keine Garantie bezüglich des Zustands des zugehörigen Prädikats beim Zurückkehren wegen Zeitablaufs.
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.
[edit] Beispiel
#include <chrono> #include <condition_variable> #include <iostream> #include <thread> std::condition_variable 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
[edit] Defect reports
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 |
[edit] 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) |