Aquí está mi contribución a la comprensión colectiva de este comportamiento ... No es mucho, solo una demostración (basada en la demostración de xkip) que muestra el comportamiento de un valor de int no volátil (es decir, "normal"), en paralelo -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 )
;
Console.WriteLine("_volatileInt="+_volatileInt);
}
}
class NormalTest
{
private int _normalInt;
public void Run() {
new Thread(delegate() { Thread.Sleep(500); _normalInt = 1; }).Start();
while ( _normalInt != 1 )
;
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();
}
}
}
Hay algunas explicaciones sucintas realmente excelentes arriba, así como algunas referencias geniales. Gracias a todos por ayudarme a entender volatile
(al menos lo suficiente como para saber que no depende de volatile
dónde fue mi primer instinto lock
).
Saludos y gracias por TODOS los peces. Keith.
PD: Me interesaría mucho una demostración de la solicitud original, que era: "Me gustaría ver un int estático volátil comportándose correctamente donde un int estático se comporta mal.
Lo intenté y fracasé en este desafío. (De hecho, me di por vencido bastante rápido ;-). En todo lo que probé con variables estáticas, se comportan "correctamente" independientemente de si son volátiles o no ... y me encantaría una explicación de POR QUÉ ese es el caso, si es que es el caso ... ¿Es eso? el compilador no almacena en caché los valores de las variables estáticas en los registros (es decir, almacena en caché una referencia a esa dirección del montón)
No, esta no es una pregunta nueva ... es un intento de devolver a la comunidad a la pregunta original.