Hier ist mein Beitrag zum kollektiven Verständnis dieses Verhaltens ... Es ist nicht viel, nur eine Demonstration (basierend auf der xkip-Demo), die das Verhalten eines flüchtigen Verses gegenüber einem nichtflüchtigen (dh "normalen") int-Wert nebeneinander zeigt -side, im selben Programm ... das war es, wonach ich gesucht habe, als ich diesen Thread gefunden habe.
using System;
using System.Threading;
namespace VolatileTest
{
class VolatileTest
{
private volatile int _volatileInt;
public void Run() {
new Thread(delegate() { Thread.Sleep(500); _volatileInt = 1; }).Start();
while ( _volatileInt != 1 )
; // Do nothing
Console.WriteLine("_volatileInt="+_volatileInt);
}
}
class NormalTest
{
private int _normalInt;
public void Run() {
new Thread(delegate() { Thread.Sleep(500); _normalInt = 1; }).Start();
// NOTE: Program hangs here in Release mode only (not Debug mode).
// See: http://stackoverflow.com/questions/133270/illustrating-usage-of-the-volatile-keyword-in-c-sharp
// for an explanation of why. The short answer is because the
// compiler optimisation caches _normalInt on a register, so
// it never re-reads the value of the _normalInt variable, so
// it never sees the modified value. Ergo: while ( true )!!!!
while ( _normalInt != 1 )
; // Do nothing
Console.WriteLine("_normalInt="+_normalInt);
}
}
class Program
{
static void Main() {
#if DEBUG
Console.WriteLine("You must run this program in Release mode to reproduce the problem!");
#endif
new VolatileTest().Run();
Console.WriteLine("This program will now hang!");
new NormalTest().Run();
}
}
}
Es gibt einige wirklich ausgezeichnete prägnante Erklärungen oben sowie einige großartige Referenzen. Vielen Dank an alle, die mir geholfen haben, meinen Kopf volatile
herumzukriegen (zumindest genug, um zu wissen, dass ich mich nicht darauf verlassen kann, volatile
wo mein erster Instinkt warlock
).
Prost und Danke für den ganzen Fisch. Keith.
PS: Ich wäre sehr an einer Demo der ursprünglichen Anfrage interessiert, die lautete: "Ich würde gerne sehen, dass sich ein statischer flüchtiger Int korrekt verhält, während sich ein statischer Int schlecht .
Ich habe diese Herausforderung versucht und bin gescheitert. (Eigentlich habe ich ziemlich schnell aufgegeben ;-). Bei allem, was ich mit statischen Vars versucht habe, verhalten sie sich "richtig", unabhängig davon, ob sie flüchtig sind oder nicht ... und ich würde gerne erklären, WARUM das der Fall ist, wenn es tatsächlich der Fall ist ... Ist es das? Der Compiler speichert die Werte statischer Variablen nicht in Registern zwischen (dh er speichert stattdessen einen Verweis auf diese Heap-Adresse zwischen).
Nein, dies ist keine neue Frage. Es ist ein Versuch, die Community auf die ursprüngliche Frage zurückzubringen.