2

コンテキストスイッチは命令の実行中の任意の時点で発生する可能性があるように見えるので、コンテキストスイッチが任意の命令間で発生する可能性があり、異なるCPU上にある可能性がある場合、「部分的に問題のある」コード(これらの2つの命令)がなぜ意味があるのか​​ 疑問に思っています2 番目の命令のコア。

void B()
  {
    Thread.MemoryBarrier();    // Barrier 3
    if (_complete)
    {
      //PART IN QUESTION
      Thread.MemoryBarrier();       // Barrier 4
      Console.WriteLine (_answer);
      //END PART IN QUESTION
    }
  }

ここでの MemoryBarrier の説明は、MemoryBarrier を呼び出した後に CPU が切り替えられないという保証を与えるようには見えませ

(これはこの質問に関連しています)

4

2 に答える 2

3

の周りでコンテキスト スイッチが発生する、または発生しないという保証はありませんMemoryBarrier。これらは直交概念です。

于 2011-08-31T17:12:33.127 に答える
2

Thread.MemorryBarrier() 呼び出し後にコンテキスト切り替えが発生しないことを保証するものは何ですか?

何もない。MemoryBarriers は、コンテキストの切り替え (またはコードのアトミック実行) を妨げません。

他の質問については、なぜバリア 4 が必要なのか:

前の質問のコード例では、バリア 4 が存在しない場合、C# コンパイラ、CLR、または CPU は、完了した変数の前に回答変数の読み取りを並べ替える可能性があります。つまり、実際に実行されるコードは次のようになります。

Thread.MemoryBarrier();    // Barrier 3
int tmpanswer = _answer;
if (_complete)
{

  Console.WriteLine (tmpanswer);
}

Console.WriteLine() の前のバリアは、読み取り_answer前の読み取りを防ぎます_completed

ただし、コード例では、void B() 内のコードについてこの 1 つの保証しか提供されていないことに注意してください (ただし、A() が1 回だけ実行される場合) 。

  • _complete 変数が true の場合、 Console.WriteLine は 0 ではなく 123 を書き込みます。

したがって、A と B が連続して実行されない限り、コードは B が常に 123 を出力するようなロック/通知を提供しません。A() と B() は実行中にいつでもインターリーブ/中断される可能性があります。誰がいつ走れるか。

2 つのスレッドを開始した順序に関係なく、B() が A() の後に実行されるという保証はありません。 () もちろん)

于 2011-08-31T17:39:53.717 に答える