std::condition_variable::wait
| void wait( std::unique_lock<std::mutex>& lock ); |
(1) | (seit C++11) |
| template< class Predicate > void wait( std::unique_lock<std::mutex>& lock, Predicate pred ); |
(2) | (seit C++11) |
wait veranlasst den aktuellen Thread zu blockieren, bis die Bedingungsvariable benachrichtigt wird oder ein sporadisches Aufwachen auftritt. pred kann optional angegeben werden, um sporadisches Aufwachen zu erkennen.
wait(lock);.
Unmittelbar nach der Rückgabe von wait 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 ebenfalls auf *this warten, ist lock.mutex() anders als der Mutex, der von den Wartefunktionen (
wait, wait_for und wait_until) entsperrt wurde, die auf *this von diesen Threads aufgerufen wurden.
- ↑ 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 |
| 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. | ||
[bearbeiten] Ausnahmen
[bearbeiten] Anmerkungen
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 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 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 oder nach Ablauf der angegebenen Timeout-Dauer (public member function) | |
| blockiert den aktuellen Thread, bis die Bedingungsvariable geweckt wird oder bis der angegebene Zeitpunkt erreicht ist (public member function) | |
| C-Dokumentation für cnd_wait
| |
[bearbeiten] Externe Links
| The Old New Thing Artikel: Spurious wake-ups in Win32 condition variables. |