Ich habe eine Frage zu folgendem Codebeispiel (entnommen aus: http://www.albahari.com/threading/part4.aspx#_NonBlockingSynch )
class Foo
{
int _answer;
bool _complete;
void A()
{
_answer = 123;
Thread.MemoryBarrier(); // Barrier 1
_complete = true;
Thread.MemoryBarrier(); // Barrier 2
}
void B()
{
Thread.MemoryBarrier(); // Barrier 3
if (_complete)
{
Thread.MemoryBarrier(); // Barrier 4
Console.WriteLine (_answer);
}
}
}
Es folgt die folgende Erläuterung:
"Die Barrieren 1 und 4 verhindern, dass dieses Beispiel "0" schreiben kann. Die Barrieren 2 und 3 bieten eine Frischegarantie: Sie stellen sicher, dass, wenn B nach A ausgeführt wird, das Lesen von _complete als wahr ausgewertet wird."
Ich verstehe, wie sich die Verwendung der Speichersperren auf die Befehlsaufzeichnung auswirkt, aber was ist das "Frische-Garantie" die erwähnt wird?
Im weiteren Verlauf des Artikels wird auch das folgende Beispiel verwendet:
static void Main()
{
bool complete = false;
var t = new Thread (() =>
{
bool toggle = false;
while (!complete)
{
toggle = !toggle;
// adding a call to Thread.MemoryBarrier() here fixes the problem
}
});
t.Start();
Thread.Sleep (1000);
complete = true;
t.Join(); // Blocks indefinitely
}
Diesem Beispiel folgt die folgende Erklärung:
"Dieses Programm wird nie beendet, da die vollständige Variable in einem CPU-Register zwischengespeichert wird. Das Einfügen eines Aufrufs von Thread.MemoryBarrier innerhalb der while-Schleife (oder das Sperren um das Lesen von complete) behebt den Fehler."
Also noch einmal ... was passiert hier?