これが、この動作の集合的な理解への私の貢献です...これは、揮発性と不揮発性(つまり「通常」)のint値の動作を並べて示すデモンストレーション(xkipのデモに基づく)だけです。 -側、同じプログラムで...これは私がこのスレッドを見つけたときに探していたものです。
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:元のリクエストのデモに非常に興味があります。「 staticintが誤動作する場所でstaticvolatileintが正しく動作することを確認したいです。
私はこの挑戦を試みて失敗しました。(実際、私はすぐに諦めました;-)。私が静的変数で試したすべてのことで、それらは揮発性であるかどうかに関係なく「正しく」動作します...そして、実際にそうである場合、なぜそうなるのかについての説明が欲しいです...それはそれですかコンパイラは静的変数の値をレジスタにキャッシュしません(つまり、代わりにそのヒープアドレスへの参照をキャッシュします)?
いいえ、これは新しい質問ではありません...コミュニティを元の質問に戻そうとする試みです。