Forum: Compiler & IDEs C++ condition_variable.wait_until von Systemzeit abhängig?


von Ratlos (Gast)


Angehängte Dateien:

Lesenswert?

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
1
[&](){ return i == 1; }
 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?

von Ratlos (Gast)


Lesenswert?

Ich nochmal:
Ein wenig Recherche ergab, dass es tatsächlich ein bekanntes Problem 
ist:
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=41861

Ich verstehe das so, dass die API-Anforderungen für condition_variable 
aus dem C++ Standard wohl nicht so einfach mit den POSIX System-Calls 
realisierbar sind. Sollte das zutreffen, finde ich das schon ziemlich 
krass. Das müsste doch viele Systeme betreffen?

Wie könnte man das jetzt umgehen?
Direkt die Linux-Calls verwenden (pthread_cond_timedwait)?

von Konrad S. (maybee)


Lesenswert?

Ratlos schrieb:
> Wie könnte man das jetzt umgehen?

Systemzeit nicht verstellen.

von tictactoe (Gast)


Lesenswert?

So nebenbei würde mich interessieren, ob wait_for auch vorzeitig 
endet...

von Ratlos (Gast)


Lesenswert?

tictactoe schrieb:
> So nebenbei würde mich interessieren, ob wait_for auch vorzeitig
> endet...

Ja, tut es auch.

von WB (Gast)


Lesenswert?

Ich habe das selbe Problem. Bei jedem neu produzierten System muss 
mindestens einmal die Uhrzeit gestellt werden. Hier gibt es somit immer 
timouts :-((

von PittyJ (Gast)


Lesenswert?

Umstellen der Uhrzeit.
Reboot und gut.

Beitrag #6502565 wurde von einem Moderator gelöscht.
Beitrag #6507351 wurde von einem Moderator gelöscht.
Beitrag #6508624 wurde von einem Moderator gelöscht.
Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.