std::condition_variable_any:: wait_until
|
template
<
class
Lock,
class
Clock,
class
Duration
>
std::
cv_status
|
(1) | (seit C++11) |
|
template
<
class
Lock,
class
Clock,
class
Duration,
class
Predicate
>
bool
wait_until
(
Lock
&
lock,
|
(2) | (seit C++11) |
|
template
<
class
Lock,
class
Clock,
class
Duration,
class
Predicate
>
bool
wait_until
(
Lock
&
lock,
std::
stop_token
stoken,
|
(3) | (seit C++20) |
wait_until
bewirkt, dass der aktuelle Thread blockiert, bis die Bedingungsvariable benachrichtigt wird, die angegebene Dauer abgelaufen ist oder ein spontanes Aufwachen auftritt.
pred
kann optional bereitgestellt werden, um spontanes Aufwachen zu erkennen.
if ( wait_until ( lock, abs_time ) == std:: cv_status :: timeout )
return pred ( ) ;
return true ; .
{
if ( pred ( ) )
return true ;
if ( wait_until ( lock, abs_time ) == std:: cv_status :: timeout )
return pred ( ) ;
}
return pred ( ) ; .
Unmittelbar nachdem
wait_until
zurückkehrt, ist
lock
durch den aufrufenden Thread gesperrt. Wenn diese Nachbedingung nicht erfüllt werden kann
[1]
, ruft es
std::terminate
auf.
- ↑ Dies kann passieren, wenn das erneute Sperren des Mutex eine Exception auslöst.
Inhaltsverzeichnis |
Parameter
| lock | - | eine Sperre, die vom aufrufenden Thread gesperrt werden muss |
| stoken | - | ein Stop-Token zur Registrierung von Unterbrechungen |
| abs_time | - | der Zeitpunkt, an dem das Warten abläuft |
| pred | - | das Prädikat zur Überprüfung, ob das Warten abgeschlossen werden kann |
| Typanforderungen | ||
-
Lock
muss die Anforderungen von
BasicLockable
erfüllen.
|
||
-
Predicate
muss die Anforderungen von
FunctionObject
erfüllen.
|
||
|
-
|
||
Rückgabewert
Ausnahmen
Hinweise
Die Norm empfiehlt, dass die an
abs_time
gebundene Uhr zur Zeitmessung verwendet wird; diese Uhr muss kein monotones Zeitgeber sein. Es gibt keine Garantien bezüglich des Verhaltens dieser Funktion, wenn die Uhr diskontinuierlich angepasst wird, aber die bestehenden Implementierungen konvertieren
abs_time
von
Clock
zu
std::chrono::system_clock
und delegieren an POSIX
pthread_cond_timedwait
, sodass das Warten Anpassungen der Systemuhr berücksichtigt, jedoch nicht die benutzerbereitgestellte
Clock
. In jedem Fall kann die Funktion auch länger warten, als bis
abs_time
erreicht wurde, aufgrund von Planungs- oder Ressourcenkonfliktverzögerungen.
Selbst wenn die verwendete Uhr std::chrono::steady_clock oder eine andere monotone Uhr ist, kann eine Systemzeitanpassung einen falschen Wakeup auslösen.
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 Gesamtreihenfolge statt, die als
Modifikationsreihenfolge
einer atomaren Variable betrachtet werden kann: Die Reihenfolge ist spezifisch für diese individuelle Condition Variable. Dies macht es unmöglich, dass
notify_one()
beispielsweise verzögert wird und einen Thread freigibt, der gerade nach dem Aufruf von
notify_one()
mit dem Warten begonnen hat.
Beispiel
#include <chrono> #include <condition_variable> #include <iostream> #include <thread> std::condition_variable_any cv; std::mutex cv_m; // Dieses Mutex wird für drei Zwecke verwendet: // 1) zum Synchronisieren von Zugriffen auf i // 2) zum Synchronisieren von Zugriffen auf std::cerr // 3) für die 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
Fehlerberichte
Die folgenden verhaltensändernden Fehlerberichte wurden rückwirkend auf zuvor veröffentlichte C++-Standards angewendet.
| DR | Angewendet auf | Verhalten wie veröffentlicht | Korrektes Verhalten |
|---|---|---|---|
| LWG 2093 | C++11 | Timeout-bezogene Ausnahmen fehlten in der Spezifikation | erwähnt diese Ausnahmen |
|
LWG 2114
( P2167R3 ) |
C++11 | Konvertierbarkeit zu 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 wirft | ruft std::terminate in diesem Fall auf |
Siehe auch
|
blockiert den aktuellen Thread, bis die Condition Variable aufgeweckt wird
(public member function) |
|
|
wait_until
|
blockiert den aktuellen Thread, bis die Condition Variable aufgeweckt wird oder der angegebene Zeitpunkt erreicht wurde
(public member function) |