3

次のようなコードで、Proc1 と Proc2 が異なるプロセッサで同時に実行される場合、ThingVal2 が 5 以外の値 (ゼロなど) を取得することは可能ですか?

クラス SimpleThing
    Public X As Integer
    Sub New (整数としての ByVal 値)
        X = 値
    サブ終了
クラス終了
クラス ConcurrencyTest
    Dim Thing1 を新しい SimpleThing として (5)
    Dim Thing2 を新しい SimpleThing として (0)
    Dim ThingRef を SimpleThing = Thing1 として
    Dim ThingVal1、ThingVal2 を整数として
    サブ Proc1()
        Thing2.X = 5
        Threading.Thread.MemoryBarrier()
        ThingRef = Thing2
    サブ終了
    サブ Proc2()
        ThingVal1 = Thing2.X
        ThingVal2 = ThingRef.X
    サブ終了
クラス終了

IA64 のような弱いモデルでは、Proc2 が ThingRef が変更されたと認識しても、Thing2 のフィールド X が変更されたと認識しない可能性が実際にあることを私は知っています。x86 または x64 で実行されている .Net アプリケーションにそのリスクは存在しますか? Proc1 が SimpleThing の新しいインスタンスを作成し、その X フィールドを 5 に設定し、ThingRef をそれを指すように設定した場合、危険を回避するにはそれで十分であるか、または新しい Thing がキャッシュ ラインに割り当てられる可能性があります。 Proc2 スレッドがアクセスした他の何かと共有されましたか?

マルチスレッド コードの一般的なパラダイムは、不変オブジェクトを構築し、それを指す可変参照を設定することです (おそらく Interlocked.CompareExchange を使用します)。x86/x64 では、スレッドに関係なく不変型を読み取ることは常に安全ですか?それとも問題を引き起こす可能性がありますか? 後者の場合、信頼できる動作を保証するためにvb.netで推奨される方法は何ですか?

また、そのような問題が発生しない方法でコードを実行する必要があることを指定する方法はありますか?

4

1 に答える 1

0

わかりました、あなたは多くの質問をしました。私が知っていることを答えようとします。

-1. あなたのコード例を宣伝してください:

2.0 以降の CLR はストアを注文しました。x86/x64 では ThingVal が常に 5 になることを意味します。確かに。実際の IA64 では試していませんが、IA64 でも同様に機能するはずです。CLR はすべてのプラットフォームで順序付けされた書き込みを保証し、単純な例では十分なはずだからです。

-2. ad IA64 対 x86/x64:

x86/x64 ではメモリ セマンティクスが異なり、IA64 のようなリスクはありません。ここで考えられる唯一の問題は、実際に高水準言語を使用していて、(C++ のように) 最適化コンパイラを使用している場合、コンパイラが最適化を行う方法を正確に知らなければ何も予測できないことです。文書化されていない: VB はグローバルな最適化などを実行しないため、コードは安全なはずです。

-3. 広告不変:

本当に読むだけで本当にイミュータブルであれば安全です。

-4. 広告シングルコア:

スレッド アフィニティを設定できます。これは各スレッドの標準プロパティであり、スレッドが実行できる CPU を定義します。(.net のスレッド アフィニティ設定は、オペレーティング システムのアフィニティを直接変更します。)しかし、プログラムの実行が遅くなります。

また、C# に切り替えてvolatileキーワードを使用することもできます。これにより、すべての CPU ですぐに認識される volatile 変数に変更が加えられ、ここで提示された可能性のあるすべての問題が解決されるため、生活が楽になります。残念ながら、VB はこのキーワードを提供していません。

于 2011-01-15T19:26:06.680 に答える