Spurious Deblockierung in boost Gewinde
-
05-07-2019 - |
Frage
ich auf diesem interessanten Absatz kam in der Boost-Thread Dokumentation heute:
void wait(boost::unique_lock<boost::mutex>& lock)
...
Effekte: Atomar Aufruf lock.unlock () und blockiert den aktuellen Thread. Das Thread entsperren, wenn von einer benannten rufen this-> notify_one () oder this-> notify_all () oder spuriously . Wenn der Faden unblockierten (für welchen Gründen auch immer) ist das Schloss reacquired durch lock.lock () aufrufen vor dem Aufruf kehrt zu warten. Das Sperre wird auch durch den Aufruf reacquired (Lock.lock), wenn die Funktion beendet mit eine Ausnahme.
Also, was mich interessiert ist die Bedeutung des Wortes „unecht“. Warum soll das Gewinde für fadenscheinige Gründe freigegeben werden? Was getan werden kann, um das zu beheben?
Lösung
Dieser Artikel von Anthony Williams ist besonders detailliert .
Unechte Nachläufe kann nicht vorhergesagt werden: sie sind im Wesentlichen zufällig aus dem Benutzer-Sicht. Aber sie häufig auftreten, wenn die Thread-Bibliothek sicherzustellen, nicht zuverlässig, dass eine Warte kann Thread wird keine Benachrichtigung übersehen. Da eine verpasste Meldung würde machen die Bedingungsvariable nutzlos, die Thread-Bibliothek weckt den Faden von seiner Warte anstatt die nehmen Risiko.
Er weist auch darauf hin, dass Sie die timed_wait
Überlastungen verwenden sollten, die eine Dauer nehmen, und Sie sollten in der Regel die Möglichkeiten nutzen, die ein Prädikat nehmen
Das ist der Fehler für Anfänger und ein das ist leicht mit einem einfachen überwinden Regel: immer überprüfen Sie Ihr Prädikat in einem Schleife, wenn sie mit einer Bedingung wartet Variable. Die heimtückischen Fehler kommen von timed_wait ().
Dieser Artikel von Vladimir Prus ist auch interessant.
Aber warum brauchen wir die while-Schleife, können wir nicht schreiben:
if (!something_happened)
c.wait(m);
Wir können nicht. Und der Mörder Grund ist, dass ‚warten‘ kann Rückkehr ohne ‚Notify‘ Anruf. Das ist falscher Wakeup genannt und ist ausdrücklich von POSIX erlaubt. Im Wesentlichen Rückkehr von ‚wait‘ nur zeigt an, dass die gemeinsam genutzten Daten könnten dass Daten geändert haben, so muss es sein ausgewertet wieder.
Okay, also warum ist dies noch nicht fest? Der erste Grund ist, dass niemand will etwas reparieren. Wrapping Aufruf von 'wait' in wird eine Schleife für mehrere sehr erwünscht andere Gründe. Aber diese Gründe Erklärung bedürfen, während unechten Wakeup ist ein Hammer, die angewendet werden können, einen Student im ersten Jahr ohne scheitern.
Andere Tipps
Dieser Blog-Eintrag gibt einen Grund für Linux, in Bezug auf Anruf Rückgabe des futex
Systems, wenn ein Signal auf ein Verfahren geliefert wird. Leider gibt es nichts anderes erklären (und in der Tat für weitere Informationen verlangt).
Wikipedia-Eintrag auf unechte Wakeups (die anscheinend ein Posix weites Konzept sein, btw, nicht darauf beschränkt) steigern könnten Sie auch interessieren.