Ось мій внесок у колективне розуміння цієї поведінки ... Це не багато, просто демонстрація (заснована на демонстрації xkip), яка показує поведінку летких віршів нелетучим (тобто "нормальним") значенням int, поруч -side, в тій самій програмі ... що я шукав, коли знайшов цю тему.
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();
}
}
}
Вище є декілька справді чудових стислих пояснень, а також кілька чудових посилань. Дякую всім за те, що допомогли мені розібратися в голові volatile
(принаймні, щоб знати, не покладатися на те, volatile
де lock
це був мій перший інстинкт ).
Вітаємо та дякуємо за ВСЮ рибу. Кіт.
PS: Я б дуже зацікавлений в демо вихідному запиті, який був: «Я хотів би бачити в статичний летючий Int поводиться правильно , де це статичний Int поводиться погано.
Я спробував і не вдався до цього виклику. (Насправді я здався досить швидко ;-). У всьому, що я пробував зі статичними варіантами, вони поводяться "правильно", незалежно від того, чи вони нестабільні ... і я хотів би пояснити ЧОМУ це так, якщо це справді так ... Чи це так? компілятор не кешує значення статичних vars в регістрах (тобто замість цього кешує посилання на цю адресу кучі)?
Ні, це не нове питання ... це спроба повернути спільноту до вихідного питання.