Ich versuche, die C # Volatile-Klasse zu verstehen.
Wie ich gelesen habe:
Die Volatile.Write
-Methode erzwingt den Wert in location, der geschrieben werden soll
bis zum Zeitpunkt des Anrufs. Außerdem jede frühere Programmbestellung
Lasten und Speicher müssen vor dem Aufruf von Volatile.Write auftreten.
Die Methode Volatile.Read
erzwingt den Wert in der Position, aus der gelesen werden soll
zum Zeitpunkt des Anrufs. Außerdem lädt jede spätere Programmreihenfolge
und Speicher müssen nach dem Aufruf von Volatile.Read auftreten.
Bedeutet das im Falle von:
%Vor% Die CPU wartet auf die Befehle vor Volatile.Write(ref m_flag, 1);
, bevor sie mit dem Schreiben in m_flag
?
Und wie hilft das der Thread-Synchronisierung?
Die CPU wartet auf die Befehle vor Volatile.Write (ref m_flag, 1); vor dem Schreiben auf m_flag?
Äh, irgendwie. Eine bessere Möglichkeit, dies zu formulieren ist: Es wird garantiert, dass m_flag
auf 1 gesetzt wird und m_value
auf 5 gesetzt wird, wenn für einen anderen Thread die Option Thread1
aktiviert ist.
Und wie hilft das der Thread-Synchronisierung?
Ich würde nicht sagen, dass es bei der Synchronisation hilft - aber es hilft beim Erreichen der Korrektheit.
Wenn Sie keine flüchtigen Lese- / Schreiboperationen verwenden, ist es möglich, dass der Compiler / runtime / cpu die beiden Anweisungen in der %code% -Methode neu anordnet, und das Programm kann entweder 0, 5 oder überhaupt nichts.
Mit den flüchtigen Lese- / Schreibvorgängen druckt das Programm entweder 5 oder gar nichts, aber nie 0. Welches ist das beabsichtigte Verhalten.
Wie hilft das die Thread-Synchronisierung?
Es hilft nicht Thread-Synchronisierung in dem Sinne, dass die Reihenfolge, in der ihre Befehle ausgeführt werden, festgelegt wird. Dadurch können Sie sicherstellen, dass ein gleichzeitiger Thread Änderungen an Werten im Speicher in einer bestimmten Reihenfolge beobachtet, wenn eine bestimmte Reihenfolge für die Logik Ihres Programms wichtig ist.
[Läuft die CPU auf die Befehle vor
Volatile.Write(ref m_flag, 1);
, bevor sie mit dem Schreiben inm_flag
beginnt?
Nein, der Befehl zum Schreiben in m_value
wurde bereits ausgeführt. Die Ergebnisse sind jedoch möglicherweise außerhalb des CPU-Kerns nicht sichtbar. Insbesondere könnte ein Thread, der auf einem anderen Kern ausgeführt wird, einen alten Wert von m_value
nach dem Befehl lesen, der 5
an ihn geschrieben hat fertig ausgeführt. Dies liegt daran, dass der neue Wert möglicherweise im Cache der CPU und nicht im Speicher liegt.
Wenn Sie
schreiben %Vor% anstelle von Volatile.Write(ref m_flag, 1)
Der andere Kern sieht die Schreibvorgänge in einer anderen Reihenfolge: zuerst würde er sehen, dass m_flag
zu 1
geworden ist, und danach würde er sehen, dass m_value
zu 5
geworden ist. Wenn Ihr anderer Thread den Wert von m_flag
verwendet, um die Gültigkeit von m_value
zu beurteilen, kann die Logik fehlerhaft sein: Beispielsweise kann Thread2
gelegentlich Null ausgeben.
Tags und Links c# volatile thread-synchronization