スレッドがロックせずAlpha
に変数に書き込んでいると仮定します。A
2番目のスレッドBeta
は終了を待機してから、変数を順番にAlpha
読み取ります。A
中身A
が新鮮でない可能性はありますか?スレッドの有効期間を超えてメモリ書き込みを遅らせることはできますか?スレッドのAlpha
終了を待機する標準のメカニズムは、暗黙的にメモリバリアとして機能しませんか?
更新1
メモリバリアを含まない待機の例はありますか?
スレッドがロックせずAlpha
に変数に書き込んでいると仮定します。A
2番目のスレッドBeta
は終了を待機してから、変数を順番にAlpha
読み取ります。A
中身A
が新鮮でない可能性はありますか?スレッドの有効期間を超えてメモリ書き込みを遅らせることはできますか?スレッドのAlpha
終了を待機する標準のメカニズムは、暗黙的にメモリバリアとして機能しませんか?
更新1
メモリバリアを含まない待機の例はありますか?
ほぼ確実に(スレッドの終了を待機するために使用されるAPIは、それ自体の目的でメモリバリアを使用する必要があります)、決定的な答えを得るには、使用されている特定のスレッドAPIについて話す必要があると思います。
たとえば、posixは次のことを保証しpthread_join()
ます:https ://stackoverflow.com/a/3208140/12711
また、Win32は、同期APIがオブジェクト(スレッドハンドルなど)を待機することでメモリバリアが発生することを文書化しています:http://msdn.microsoft.com/en-us/library/ms686355.aspx
これは、スレッドライブラリが提供する保証によって異なります。特に、pthread_join()はメモリバリアとして定義されています。ほとんどの場合、スレッドの結合にはメモリバリアが伴いますが、これが常に当てはまるとは限らないことも考えられます。
(C#を参照していると仮定します。)
あなたがThread
文字通り意味するなら、あなたの答えは暗黙的にメモリバリアを生成するかどうかに依存しますThread.Join
(すでに与えられた答えによれば、それはおそらくそうします)。
ただし、Alpha
とBeta
がバックグラウンドスレッド(おそらくスレッドプールから)で実行されるユーザー定義タスクであり、「待機中」が2つのタスク間のユーザーレベルの同期を指す場合、データは実行されない可能性が高くなります。シグナリング構造または明示的なバリアが導入されていない限り、新鮮である必要があります。
簡単な例を次に示します。
public class Program
{
static string A = "foo";
static volatile bool isAlphaReady = false;
static void Alpha()
{
A = "bar";
isAlphaReady = true;
}
static void Beta()
{
while (!isAlphaReady)
; // Wait by polling
Console.WriteLine(A);
}
static void Main(string[] args)
{
new Thread(Alpha).Start();
new Thread(Beta).Start();
Console.ReadKey();
}
}
常にの値としてBeta
出力されるように見えますが(Itaniumなど)、同期動作が弱いマルチプロセッサシステムでは保証されません。その場合、代わりに出力される可能性があります。"bar"
A
"foo"