aquí está mi contribución a la comprensión colectiva de este comportamiento ... No es mucho, sólo una demostración (basado en el demo de xkip), que muestra el comportamiento de una volátil versos no volátil (es decir, "normal") int value, side-by-side, en el mismo programa ... que es lo que estaba buscando cuando encontré este hilo.
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();
}
}
}
Existen algunas explicaciones sucintas muy excelentes, así como algunas referencias excelentes. Gracias a todos por ayudarme a entender volatile
(al menos lo suficiente como para saber que no confío en volatile
donde mi primer instinto fue lock
).
Saludos, y gracias por TODO el pez. Keith.
PS: Estaría muy interesado en una demostración de la solicitud original, que era: "Me gustaría ver un estática volátil int comportarse de manera adecuada cuando un estática int se porta mal.
he usado sin éxito este reto. (En realidad me dio bastante rápido ;-). En todo lo que probé con vars estáticos que se comportan de manera "correcta", independientemente de si están o no volátil ... y me encantaría una explicación de POR QUÉ ese es el caso, si es así ... Es que el compilador no almacena en caché los valores de variables estáticas en los registros (es decir, almacena en caché una referencia a esa dirección de montón en su lugar)?
No, esta no es una nueva pregunta ... es un intento de superar la comunidad a la pregunta original.
Probado en .NET 4.0, tanto x86 como x64: pueden confirmar que el ejemplo sigue siendo aplicable. ¡Gracias! :) –
¡Eso es bueno!Nunca supe que el JIT realiza este tipo de optimización y que volátil lo desactiva. – usr
Solo para ser explícito, está agregando la palabra clave "volátil" a la declaración de foo, ¿verdad? – JoeCool