std::condition_variable_any::wait
| template< class Lock > void wait( Lock& lock ); |
(1) | (seit C++11) |
| template< class Lock, class Predicate > void wait( Lock& lock, Predicate pred ); |
(2) | (seit C++11) |
| template< class Lock, class Predicate > bool wait( Lock& lock, std::stop_token stoken, Predicate pred ); |
(3) | (seit C++20) |
wait bewirkt, dass der aktuelle Thread blockiert wird, bis die Bedingungsvariable benachrichtigt wird oder ein sporadischer Aufwachvorgang eintritt. pred kann optional angegeben werden, um sporadische Aufwachvorgänge zu erkennen.
wait(lock);
{
if (pred())
return true;
wait(lock);
}
return pred();
Direkt nach der Rückgabe von wait wird 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 |
[edit] Parameter
| lock | - | ein Lock, der vom aufrufenden Thread gesperrt sein muss |
| stoken | - | ein Stop-Token, um die Unterbrechung dafür zu registrieren |
| 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. | ||
[edit] Rückgabewert
[edit] Ausnahmen
[edit] Hinweise
Der Rückgabewert von Überladung (3) gibt an, ob pred zu true ausgewertet wurde, unabhängig davon, ob eine Stoppanforderung gestellt wurde oder nicht.
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_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
[edit] 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 |
[edit] 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
| |
[edit] Externe Links
| Artikel "The Old New Thing": Spurious wake-ups in Win32 condition variables. |