C# 4 の概要 (強くお勧めします) では、次のコードを使用して MemoryBarrier の概念を示します (A と B が異なるスレッドで実行されたと仮定します)。
class Foo{
int _answer;
bool complete;
void A(){
_answer = 123;
Thread.MemoryBarrier(); // Barrier 1
_complete = true;
Thread.MemoryBarrier(); // Barrier 2
}
void B(){
Thread.MemoryBarrier(); // Barrier 3;
if(_complete){
Thread.MemoryBarrier(); // Barrier 4;
Console.WriteLine(_answer);
}
}
}
彼らは、バリア 1 と 4 がこの例が 0 を書き込むのを防ぎ、バリア 2 と 3 が新鮮さを保証することを述べています。B が A の後に実行された場合、読み取り_completeがtrueと評価されることを保証します。
私は本当にそれを得ていません。バリア 1 と 4 が必要な理由を理解していると思います: _answer への書き込みを最適化して_completeへの書き込みの後に配置することは望ましくなく(バリア 1)、_answer がキャッシュされないようにする必要があります(バリア 4) 。 . また、バリア 3 が必要な理由も理解していると思います。A が_complete = trueを書き込んだ直後まで実行された場合、B は正しい値を読み取るために_completeを更新する必要があります。
なぜバリア 2 が必要なのかわかりません。私の一部は、おそらくスレッド 2 (B を実行中) がすでにif(_complete)まで実行されていたため (ただし、含まれていないため)、 _completeが更新さ れていることを確認する必要があると言っています。
ただし、これがどのように役立つかわかりません。A で_completeが true に設定されていても、B メソッドでは_completeのキャッシュ (false) バージョンが表示される可能性はありませんか? つまり、スレッド 2 が最初の MemoryBarrier の後までメソッド B を実行し、次にスレッド 1 がメソッド A を_complete = trueまで実行し、それ以上実行せず、スレッド 1 が再開してif(_complete)をテストした場合、そうでない場合はfalseになりますか?