Eine atomare Bool "bereit" wird zwischen zwei Threads geteilt. Thread A führt eine Aufgabe aus, und Thread B wartet darauf, von A benachrichtigt zu werden. A wird "fertig" auf "True" setzen, wenn die Aufgabe abgeschlossen ist.C++ atomare Speicherreihenfolge vs Thread-Ereignisse wie notify()
B hat ein Warte-Prädikat, das "fertig" testet. Wenn "fertig" nach dem Aufwachen immer noch "Falsch" ist, kehrt B zum Warten zurück. (Dies verhindert, dass unerwünschte Nachläufe von Ärger)
A seine Aufgabe beendet hat, setzt „bereit“ auf True, benachrichtigt dann
B.Frage: Wie kann ich B garantieren lesen (Last) „ready“ als wahr und nicht der ältere False?
Ich habe festgestellt, dass manchmal B liest "bereit" als False, und wacht nie auf. Was bedeutet, aus seiner Sicht kam die Benachrichtigung vor das Update, obwohl in A die Bestellung ist Update, dann notify.
HINWEISE: Ich habe zu viel über Speicherbestellung Garantien gelesen, und ich denke, ich verstehe genug über lesen und schreiben bestellen. Diese Frage beinhaltet jedoch die Bestellung von Speicher-Updates und Thread-Kommunikationsereignisse, nämlich notify. Ich kann keine klare Antwort finden, wie ich die Bestellung garantieren kann.
Siehe zB: http://www.developerfusion.com/article/138018/memory-ordering-for-atomic-operations-in-c0x/
http://bartoszmilewski.com/2008/12/01/c-atomics-and-memory-ordering/
Memory ordering behavior of std::atomic::load
Siehe auch C++ 11-Standard Abschnitt 29.3
UPDATE: Sorry für die Verwirrung, über die ist Pseudo-Code nur , von einem viel größeren Körper eingekocht und ich habe Dinge weggelassen, die nicht in das Problem suc eingreifen h als die Existenz eines Mutex auf der Zustandsvariablen. Der Arbeitscode weist die beschriebene Neuordnung des Variablenupdates auf und meldet etwa einmal alle 400 Tage Laufzeit - in der Praxis also 3-4 pro Tag. Diese ist tatsächlich passiert.
Ich denke, alles, was fehlt, ist die "Rückkehr" in Ihrem Lambda. Dein Compiler sollte davor warnen; es macht das Lambda jedes Mal zu einem im Wesentlichen zufälligen Wert. – Cameron
@Cameron mein Fehler, ist das oben genannte Spielzeug Pseudocode das Problem von einem viel größeren Körper, nicht wirklich funktionierenden Code. Das Ereignis, das ich beschreibe, passiert ungefähr alle ~ 400 Tage Laufzeit. – bulletsweetp
Der Aufruf von 'B_cond_var.notify_one()' ist nicht in Bezug auf die Zugriffe auf 'atomic ready' angeordnet (nach meinem Verständnis sind 'atomare <> 'Instanzen geordnet nur in Bezug auf sich selbst). Ich glaube, du musst den Mutex halten, während du 'fertig 'aktualisierst, was jeden Vorteil von' bereit ', atomar zu sein, eliminieren kann. –