次のようなコードでは、Proc1とProc2が異なるプロセッサで同時に実行される場合、ThingVal2が5以外の値(たとえばゼロ)を取得することは可能ですか?フィールドを参照解除するときにメモリバリアが必要(.net x86またはx64)ですか?
Class SimpleThing Public X As Integer Sub New(ByVal value As Integer) X = value End Sub End Class Class ConcurrencyTest Dim Thing1 As New SimpleThing(5) Dim Thing2 As New SimpleThing(0) Dim ThingRef As SimpleThing = Thing1 Dim ThingVal1, ThingVal2 As Integer Sub Proc1() Thing2.X = 5 Threading.Thread.MemoryBarrier() ThingRef = Thing2 End Sub Sub Proc2() ThingVal1 = Thing2.X ThingVal2 = ThingRef.X End Sub End Class
私は、IA64のような弱いモデルでは、はProc2が変わったとThingRef見るが、そうしたとしてThing2のフィールドXが表示されない可能性が現実の可能性があることを知っています。 x86またはx64上で実行されている.Netアプリケーションの場合、そのリスクは存在しますか? Proc1がSimpleThingの新しいインスタンスを作成し、そのXフィールドを5に設定し、ThingRefを指すように設定すると、危険を回避するのに十分であるか、新しいものがキャッシュラインに割り当てられる可能性があります。 Proc2スレッドがアクセスした何か他のものと共有されましたか?
マルチスレッドコードの一般的なパラダイムは、不変オブジェクトを作成し、それを指すように(おそらくInterlocked.CompareExchangeを使用して)変更可能な参照を設定することです。スレッド化に関係なく不変型を読むことはx86/x64上では常に安全ですか、それとも問題を引き起こす可能性がありますか?後者の場合、信頼できる動作を保証するためにvb.netでどのような方法が好まれますか?
また、このような問題が発生しないような方法でコードを実行する必要があることを指定する方法はありますか(たとえば、IA64のように正しい動作を保証できない単一のコアに実行を制限するなど)
不変は、その値を1サイクルで読み取ることができる場合にのみ保証されます。 Intとboolはそのカテゴリに分類されます。長い間、そして確かに文字列ではないことは確かではありません。 – SRM
@SRM:不変オブジェクトは、他の誰かが参照を利用できるようになると決して変更されないオブジェクトです。上記の「SimpleThing」オブジェクトは、.net x86および.net x64メモリモデルで保証されているかどうかを正確に確認しようとしているため、不変ではありません。 – supercat