Hallo,
ein Thread soll so lange auf einer condition_variable warten bis a) ein
Thread dessen notify aufruft oder b) ein Timeout abgelaufen ist.
Der folgende Code funktioniert und es wird bei Nichterhalten eines
Signals ein Timeout nach 15 Sekunden ausgelöst (vollständiger Code im
Anhang):
1 | std::unique_lock<std::mutex> lk(cv_m);
|
2 |
|
3 | auto absTimeout = std::chrono::steady_clock::now() + 15s;
|
4 | if (cv.wait_until(lk, absTimeout, [&](){ return i == 1; })) {
|
5 | // signal received
|
6 | }
|
7 | else {
|
8 | // timeout
|
9 | }
|
Wenn ich jetzt aber innerhalb der 15 Sekunden die Systemzeit vorstelle
führt das ebenfalls zu einem sofortigen Timeout. Die verwendete
steady_clock ist aber monotonic, also von Zeitänderungen eigentlich
unabhängig.
Unter
https://en.cppreference.com/w/cpp/thread/condition_variable/wait_until
steht:
> Even if the clock in use is std::chrono::steady_clock or another monotonic
clock, a system clock adjustment may induce a spurious wakeup.
Ein "spurious wakeup" sollte aber im wait_until durch das Predicate
verhindert werden, richtig?
Was noch gegen einen "spurious wakeup" spricht, ist, dass das Vorstellen
der Systemzeit unmittelbar zum Timeout führt, ein Zurückstellen diesen
jedoch zeitlich entsprechend verlängert.
Also scheint die condition_variable tatsächlich die Systemzeit zu
verwenden (entgegen der Beschreibung auf oben verlinkter Seite).
Ich habe es auf zwei Plattformen probiert (Ubuntu 16.04 64 Bit und 32
Bit embedded Linux) und immer das selbe Ergebnis erhalten. Es kann doch
nicht sein, dass das jeweils ein Fehler in der C++ Lib ist, oder etwa
doch?