Voici ma contribution à la compréhension collective de ce comportement... C'est pas beaucoup, juste une démonstration (basé sur xkip la démo) qui montre le comportement de la volatilité et de versets non volatile (c'est à dire "normal") int valeur, côte-à-côte, dans le même programme... qui est ce que je cherchais quand j'ai trouvé ce fil de discussion.
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 vraiment de super succincte les explications ci-dessus, ainsi que quelques belles références. Merci à tous de m'avoir aidé à obtenir ma tête autour de volatile
(au moins assez pour savoir de ne pas s'appuyer sur volatile
où mon premier instinct a été de lock
).
À bientôt, et Merci pour TOUT le poisson. Keith.
PS: je serais très intéressé par une démo de la demande initiale, qui était: "j'aimerais voir une statique volatile int se comporter correctement dans le cas où un static int 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 statique vars ils se comporter correctement "" indépendamment de si oui ou non ils sont volatiles ... et j'aimerais une explication de POURQUOI c'est le cas, si c'est le cas... Est-ce que le compilateur ne met pas en cache les valeurs de la statique vars dans les registres (c'est à dire qu'il met en cache une référence à ce tas d'adresse à la place)?
Non ce n'est pas une nouvelle question... c'est une tentative de tsar de la communauté revenir à la question initiale.