Voici ma contribution à la compréhension collective de ce comportement ... Ce n'est pas grand chose, juste une démonstration (basée sur la démo de xkip) qui montre le comportement d'un volatile vers une valeur int non volatile (ie "normale"), côte à côte -côté, dans le même programme ... c'est ce que je cherchais quand j'ai trouvé ce fil.
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();
}
}
}
Il y a quelques excellentes explications succinctes ci-dessus, ainsi que quelques bonnes références. Merci à tous de m'avoir aidé à comprendre volatile
(au moins assez pour savoir ne pas se fier à volatile
mon premier instinct lock
).
Bravo et merci pour TOUS les poissons. Keith.
PS: Je serais très intéressé par une démo de la requête originale, qui était: "Je voudrais voir un int statique volatile se comporter correctement là où un int statique se comporte mal.
J'ai essayé et échoué ce défi. (En fait j'ai abandonné assez rapidement ;-). Dans tout ce que j'ai essayé avec des variables statiques, ils se comportent "correctement", qu'ils soient volatils ou non ... et j'aimerais une explication de POURQUOI c'est le cas, si c'est effectivement le cas ... le compilateur ne met pas en cache les valeurs des variables statiques dans les registres (c'est-à-dire qu'il met en cache une référence à cette adresse de tas à la place)?
Non , ce n'est pas une nouvelle question ... il est une tentative de la communauté TSAR revenir à la question initiale.