4

1つのロックコードブロック内に共有変数の複数の割り当てがある場合、これらの変更はすべて他のスレッドにすぐに表示され、同じオブジェクトでロックステートメントを入力すると他のプロセッサで実行される可能性があることを意味しますか?またはそのようなものはありません保証?

そこにある多くの例は、共通変数の単一の「セット」または「get」を示し、メモリバリアの詳細を説明していますが、より複雑なステートメントのセットが内部にある場合はどうなりますか?他のことをする関数呼び出しでさえある可能性がありますか?

このようなもの:

lock(sharedObject)
{
  x = 10;
  y = 20;
  z = a + 10;
}

このコードが別のスレッドで実行されている場合(別のプロセッサで実行されている可能性があります)、変更の「可視性」について保証はありますか?

lock (sharedObject)
{
  if (y == 10)
  {
     // Do something. 
  }
}

答えが「いいえ」の場合、おそらく、これらの変更がいつ表示されるかについての説明はありますか?

4

2 に答える 2

5

ロック ブロックには、開始時と終了時 (ブロックの開始と終了) にメモリ フェンスが含まれます。これにより、メモリに対するすべての変更が他のコア (たとえば、他のコアで実行されている他のスレッド) から見えるようになります。あなたの例では、最初のロック ブロックの x、y、z への変更は、他のスレッドに表示されます。「可視」とは、レジスタにキャッシュされた値がメモリにフラッシュされ、CPU のキャッシュにキャッシュされたメモリが物理メモリにフラッシュされることを意味します。ECMA 334 は、ロック ブロックが Monitor.Enter と Monitor.Exit で囲まれたブロックであることを詳述しています。さらに、ECMA 335 は、Monitor.Enter が「揮発性の読み取り操作を暗黙的に実行するものとします...」と Monitor.Exit が「揮発性の書き込み操作を暗黙的に実行します。これは、変更が無効であることを意味します」と詳述しています。

これは事実上、lock ステートメントによって保護された変数を、その変更を他のスレッドから見えるようにするために volatile として宣言する必要がないことを意味します。

サンプル コードには、単一の共有アトミック操作 (y への単一の値の読み取りと書き込み) に依存する操作のみが含まれているため、次の方法でも同じ結果を得ることができます。

try
{
  x = 10;
  y = 20;
  Thread.VolatileWrite(ref z, a + 10);
}

if(y == 10)
{
// ...
}

最初のブロックは、x への書き込みが y への書き込みの前に表示され、y への書き込みが z への書き込みの前に表示されることを保証します。また、x または y への書き込みが CPU キャッシュにキャッシュされていた場合、そのキャッシュがVolatileWrite の呼び出しの直後に物理メモリにフラッシュされる (したがって、他のスレッドから見えるようになる)ことも保証されます。

ブロック内でandを使用if(y == 10)して何かを行う場合は、キーワードの使用に戻る必要があります。xylock

さらに、以下は同一です。

try
{
  x = 10;
  y = 20;
  Thread.MemoryBarrier();
  z = a + 10;
}
于 2012-07-23T13:51:49.470 に答える
1

私があなたの質問を誤解している場合はご容赦ください (非常に可能性があります)。しかし、同期可視性の概念が混同された状態で操作していると思います。

ミューテックス (「相互排除」) の要点は、2 つのコード ブロックが同時に実行されないようにすることです。あなたの例では、最初のブロック:

lock(sharedObject)
{
  x = 10;
  y = 20;
  z = a + 10;
}

...そして 2 番目のブロック:

lock (sharedObject)
{
  if (y == 10)
  {
     // Do something. 
  }
}

...同時に実行されることはありません。これは、lockキーワードが保証するものです。

したがって、コードが 2 番目のブロックに入るたびに、変数xy、およびzは、最初のブロックの完全な実行と一致する状態になるはずです。(これは、これらの変数にアクセスするすべての場所で、これらのスニペットと同じ方法でlockアクセスできることを前提としています。)sharedObject

xこれが意味することは、最初のブロック内の中間変更の「可視性」は、2 番目のブロックの観点からは無関係であるということyですz

于 2012-07-23T04:45:34.700 に答える