Ich habe den Artikel Synchronization and Multiprocessor Issues gelesen und ich habe eine Frage zu InterlockedCompareExchange und InterlockedExchange. Die Frage bezieht sich eigentlich auf das letzte Beispiel in dem Artikel. Sie haben zwei Variablen iValue
und fValueHasBeenComputed
und in CacheComputedValue()
modifizieren sie jede mit InterlockedExchange
:
Ich verstehe, dass ich InterlockedExchange
für die Änderung von iValue
verwenden kann, aber es genügt,
Ist es also notwendig, InterlockedExchange
zu verwenden, um iValue zu setzen? Oder andere Threads sehen iValue korrekt, auch wenn iValue = ComputeValue();
. Ich meine, die anderen Threads sehen iValue korrekt, weil InterlockedExchange
dahinter steht.
Es gibt auch das Papier Ein prinzipienbasiertes sequenzielles Speichermodell für Microsoft Native Code-Plattformen . Es gibt das 3.1.1 Beispiel mit mehr oder weniger dem gleichen Code. Eine der Empfehlungen Make y interlocked
. Hinweis - nicht sowohl y
als auch x
.
Aktualisieren
Nur um die Frage zu klären. Das Problem ist, dass ich einen Widerspruch sehe. Das Beispiel aus "Synchronization and Multiprocessor Issues" verwendet zwei InterlockedExchange
. Im Gegensatz dazu gibt Herb Sutter in dem Beispiel 3.1.1 "Basic Reodering" (das meiner Meinung nach dem ersten Beispiel sehr ähnlich ist) diese Empfehlung.
"Verschränkt machen: Wenn y verriegelt ist, gibt es keine Wettfahrt auf y weil es atomar aktualisierbar ist und es keine Rasse auf x gibt, weil a - & gt; b - & gt; d. "
. In diesem Entwurf verwende Herb nicht zwei verschränkte Variablen (Wenn ich recht habe, meint er InterlockedExchange
nur für y
).
Sie haben das getan, um partielles Lesen / Schreiben zu verhindern, wenn die Adresse von iValue
nicht auf eine Adresse ausgerichtet ist, die atomaren Zugriff garantiert. Dieses Problem tritt auf, wenn zwei oder mehr physische Threads versuchen, den Wert gleichzeitig zu schreiben, oder wenn einer liest und einer versucht, gleichzeitig zu schreiben.
Als sekundärer Punkt ist anzumerken, dass Speicher nicht immer global sichtbar sind. Sie werden nur dann sichtbar sein, wenn sie serialisiert werden, entweder durch einen Zaun oder durch eine Bussperre.
Sie erhalten einfach eine atomare Operation mit InterlockedExchange
. Warum brauchst Du es?
Ursache InterlockedExchange
macht 2 Dinge.
Wenn Sie in 2 Operationen die gleichen Dinge machen (also zuerst den Wert prüfen und dann ersetzen), können Sie sich schinden lassen, wenn zwischen diesen 2 andere Anweisungen (in einem anderen Thread) auftreten.
Und Sie verhindern auch Datenrennen über diesen Wert. hier erhalten Sie eine gute Erklärung warum lesen / schreiben auf einem LANG ist nicht atomar
Es gibt zwei plausible Lösungen für den Widerspruch, den Sie beobachtet haben.
Erstens ist das zweite Dokument in dieser Hinsicht einfach falsch. Es ist schließlich ein Entwurf. Ich bemerke, dass das Beispiel, auf das Sie sich beziehen, ausdrücklich besagt, dass der Programmierer sich nicht darauf verlassen kann, dass die Schreiboperationen atomar sind, was bedeutet, dass beide Schreiboperationen tatsächlich miteinander verknüpft sein müssen.
Das andere ist, dass die zusätzliche Verriegelung in diesem speziellen Beispiel möglicherweise nicht erforderlich ist, weil es ein ganz besonderer Fall ist: nur ein einzelnes Bit der Variablen wird geändert. Allerdings scheint die Spezifikation, die entwickelt wird, dies nicht als Prämisse zu erwähnen, also bezweifle ich, dass dies beabsichtigt ist.
Ich denke, diese Diskussion hat die Antwort auf die Frage: Implizite Speicherbarrieren .
Frage : ruft InterlockedExchange (impliziter Vollzaun) in T1 auf und T2, Gurenness, dass T2 den von T1 vor dem Schreiben durchgeführten Schreibvorgang "sieht" Zaun? (A-, B- und C-Variablen), obwohl diese Variablen nicht sind auf der gleichen Cache-Line wie Foo und Bar?
Antwort : Ja - der vollständige Zaun, der von InterlockedExchange generiert wird garantieren, dass die Schreibvorgänge nach A, B und C nicht über die Zeit nachbestellt werden Implizierter InterlockedExchange-Aufruf. Das ist der Punkt von Speicherbarrierensemantik. Sie müssen nicht im selben Cache sein Linie.
Speicherbarrieren: eine Hardware-Ansicht für Software-Hacker und < a href="http://msdn.microsoft.com/en-us/library/ee418650%28VS.85%29.aspx"> Sperrenlose Programmierung Überlegungen für Xbox 360 und Microsoft Windows sind auch sehr interessant. p>
Tags und Links c++ windows winapi atomic interlocked