Вот мой вклад в коллективное понимание этого поведения ... Это не так много, просто демонстрация (на основе демоверсии xkip), которая показывает поведение изменчивых стихов в энергонезависимом (то есть "нормальном") значении int, бок о бок, в той же программе ... что я и искал, когда нашел эту тему.
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: /95466/illystrirovanie-ispolzovaniya-klychevogo-slova-volatile-v-c-#
// 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();
}
}
}
Есть несколько действительно превосходных кратких объяснений выше, а также несколько замечательных ссылок. Спасибо всем, кто помог мне разобраться с volatile
(по крайней мере, достаточно, чтобы знать, не полагаться на volatile
, где мой первый инстинкт был lock
это).
Приветствия, и спасибо за всю рыбу. Кит.
PS: Я бы очень заинтересовался демонстрацией исходного запроса: «Я хотел бы видеть a static volatile int * 1017» * ведет себя правильно, где a статический int плохо себя ведет.
Я пробовал и провалил этот вызов. (На самом деле я сдался довольно быстро ;-). Во всем, что я пробовал со статическими переменными, они ведут себя «правильно», независимо от того, являются ли они изменчивыми ... и я бы с удовольствием объяснил, ПОЧЕМУ это так, если это действительно так ... Неужели компилятор не кеширует значения статических переменных в регистрах (то есть вместо этого кеширует ссылку на этот адрес кучи)?
Нет, это не новый вопрос ... это попытка привлечь сообщество назад к первоначальному вопросу.