これは、この動作の集合的な理解への私の貢献です...それはそれほどではありません。 -側、同じプログラムで...これは私がこのスレッドを見つけたときに探していたものです。
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();
}
}
}
上記のいくつかの本当に優れた簡潔な説明といくつかの素晴らしい参考文献があります。私の頭をvolatile
動かすのを手伝ってくれたすべてに感謝します(volatile
私の最初の本能がどこだったかに依存しないことを知るのに少なくとも十分lock
です)。
乾杯、そしてすべての魚に感謝します。キース。
PS:「私が見てみたい:私は非常にした元の要求のデモに興味があると思い静的揮発性のint正しく動作静的の int型の誤動作だけを。
私はこの挑戦を試み、失敗しました。(実際、私はかなり早くあきらめました;-)。私が静的変数で試したすべてにおいて、それらは揮発性であるかどうかに関係なく「正しく」動作します...そして実際にそうである場合、私はなぜそうであるかについての説明が欲しいです...コンパイラーは静的変数の値をレジスターにキャッシュしません(つまり、代わりにそのヒープ・アドレスへの参照をキャッシュします)?
ありませんこれは新しい問題ではない...それはコミュニティStear氏しようとする試みだ背中を元の質問に。