Ich habe die Antwort auf diese Frage bezüglich des volatilen Schlüsselworts gelesen:
Die Person sagt:
Die Lösung zum Verhindern von Neuordnung ist die Verwendung einer Speicherbarriere, welches sowohl dem Compiler als auch der CPU anzeigt, dass kein Speicherzugriff möglich ist kann über diesen Punkt neu geordnet werden. Solche Barrieren um unsere volatile variable access stellt sicher, dass auch nicht-flüchtige Zugriffe nicht funktionieren über die flüchtige neu geordnet werden, so dass wir threadsicher schreiben können Code.
Speichersperren stellen jedoch auch sicher, dass alle ausstehenden Lese- / Schreibvorgänge ausgeführt werden ausgeführt, wenn die Barriere erreicht ist, so gibt es uns effektiv alles, was wir brauchen, um Volatilität unnötig zu machen. Wir können einfach Entfernen Sie das flüchtige Qualifikationsmerkmal vollständig.
Wie ist diese "Speicherbarriere" in C ++ implementiert?
BEARBEITEN:
Könnte jemand bitte ein einfaches Codebeispiel geben?
Dies ist sehr hardwareabhängig. Von der ziemlich langen Dokumentation der Speicherbarriere des Linux-Kernels:
%Vor% Nehmen wir eine davon besonders: smp_mb()
.
Wenn Sie asm/x86/um/asm/barrier.h
öffnen, werden Sie feststellen, dass wenn CONFIG_SMP
definiert ist,
Und wenn Sie nach oben scrollen, sehen Sie, dass mb abhängig von der Plattform verschiedene Implementierungen hat:
%Vor%Weitere Informationen zu den Unterschieden zwischen diesen beiden Dingen wurden in diesem Thema besprochen . Ich hoffe, das hilft.
Speicherbarrieren sind in C ++ 11 einfach zu verwenden:
%Vor% Alle Zugriffe auf i
werden durch Speicherbarrieren geschützt.
Typischerweise gibt es "intrinsische Funktionen" - das sind spezielle Funktionen, bei denen der Compiler spezielle Kenntnisse darüber hat, wie sie funktionieren (insbesondere, dass sie Speicherbarrieren sind). Die Namen variieren von Compiler zu Compiler (und manchmal für verschiedene Architekturen desselben Compilers).
Zum Beispiel verwendet MSVC _ReadBarrier
, WriteBarrier
und _ReadWriteBarrier
In x86 würde es eine Anweisung lfence
, sfence
oder mfence
erzeugen, die jeweils Barrieren "lädt", "speichert" und "alle Speicheroperationen" - mit anderen Worten ein lfence
ist eine Barriere für Speicherleseoperationen, ein sfence
ist eine "Speicherschreibbarriere" und mfence
wird eine Barriere gegen sowohl Lese- als auch Schreiboperationen sein.
Tags und Links c++ multithreading volatile