const auto duration = Returns_10_seconds();
while(cv.wait_for(lock, duration) == std::cv_status::timeout);
Dies ist definitiv eine falsche Sache zu tun und somit keinen Sinn macht, zu diskutieren, wie es für den Fall der unechten Wakeups zu beheben, wie es auch für den Fall der gewöhnlichen Wakeups gebrochen ist, weil die Die Wartebedingung wird nach der Rückkehr von der Warte nicht erneut überprüft.
const auto duration = Returns_10_seconds();
while(!Predicate())
cv.wait_for(lock, duration);
Auch nach dem bearbeiten, bleibt die Antwort die gleiche: man kann nicht wirklich „unechte Wakeups“ behandeln, weil man nicht wirklich den Grund für die Wake-up sagen kann - es auch ein vollständig sein kann, Legit Wakeup aufgrund eines Anrufs zu condition_variable::notifyXXX
vor dem Timeout abgelaufen ist.
Beachten Sie zuerst, dass Sie nicht wirklich unterscheiden zwischen einem Aufwecken, der durch einen Anruf auf condition_variable::notifyXXX
verursacht wurde, und einem Weckruf, der zum Beispiel durch ein POSIX-Signal verursacht wurde [1]. Zweitens, auch wenn POSIX-Signale keine Rolle spielen, muss der wartende Thread die Bedingung noch einmal überprüfen, da die Bedingung zwischen dem Zeitpunkt, zu dem die Zustandsvariable signalisiert wird, und dem wartenden Thread von der Zustandswarte zurückkehrt.
Was Sie wirklich tun müssen, ist in einer besonderen Weise zu behandeln, nicht vor dem Timeout aufwachen, aber wegen Timeout aufwachen.Und das hängt vollständig von den Gründen ab, um eine Auszeit an erster Stelle zu haben, d. H. An den Besonderheiten der Anwendung/Problemdomäne.
[1], wenn auf einer Bedingungsvariable warten durch ein Signal unterbrochen wird, nachdem der Thread die Signal-Handler Ausführung erlaubt wird entweder warten wieder aufnehmen oder Rückkehr
Es tut es nicht. Sie müssen es entweder selbst überprüfen oder die Überladung verwenden, die das für Sie tut (diejenige, die ein Prädikat übernimmt). –
@MaiLongdong, wird das Prädikat verwendet, um nur solche Wakeups zu kontern. Sogar 'wait_for()' wenn es in meiner Plattform gut funktioniert, garantiert nicht, dass es überall funktioniert, weil unechte wakesups plattformabhängig sind. – iammilind
Wenn du nicht 'wait_for' 10 Sekunden lang willst benutze' wait_until' 'now()' + 10 Sekunden :-) –