C++ condition_variable.wait_until von Systemzeit abhängig?

Gast #5633122
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?
Angehängte Dateien:
Gast #5633196
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)?
Beitrag #6502565 wurde von einem Moderator gelöscht.
Beitrag #6507351 wurde von einem Moderator gelöscht.
Beitrag #6508624 wurde von einem Moderator gelöscht.

Antwort schreiben

Hinweis: der ursprüngliche Beitrag ist mehr als 6 Monate alt. Bitte hier nur auf die ursprüngliche Frage antworten, für neue Fragen einen neuen Beitrag erstellen.

Formatierung
  • [c]C-Code[/c]
  • [code]Code in anderen Sprachen, ASCII-Zeichnungen[/code]
  • [math]Formel in LaTeX-Syntax[/math]
  • [[Titel]] – Link zu einem Artikel
  • Verweis auf einen anderen Beitrag: Rechtsklick auf dessen Beitrags-ID (#8078628), „Adresse kopieren“, in den Text einfügen

Mehr zur Formatierung

Längeren Sourcecode als Anhang, nicht in den Text. JPG nur für Fotos und Scans; Zeichnungen und Screenshots als PNG oder GIF. Siehe Bildformate.

Schon registriert? Anmelden

Wird nicht angezeigt. Wir schicken dir einen Link; sobald du damit bestätigst, erscheint dein Beitrag.

Mit dem Abschicken legst du einen kostenlosen Account an und erkennst die Nutzungsbedingungen und die Datenschutzerklärung an.