3

次の擬似コードがある場合:

sharedVariable = somevalue;
CreateThread(threadWhichUsesSharedVariable);

マルチコアCPUが、親スレッドが書き込む前にsharedVariableの値を読み取るthreadWhichUsesSharedVariable()でコードを実行することは理論的に可能ですか?競合状態のごくわずかな可能性さえも完全に理論的に回避するために、コードは代わりに次のようになります。

sharedVariableMutex.lock();
sharedVariable = somevalue;
sharedVariableMutex.unlock();
CreateThread(threadWhichUsesSharedVariable);

基本的に、スレッドの生成がその時点でCPUを明示的に線形化するかどうかを知りたいのですが、そうすることが保証されています。

スレッド作成のオーバーヘッドはおそらくこれが実際には問題にならないほど十分な時間がかかることを私は知っていますが、私の完璧主義者は理論的な競合状態を恐れています。一部のスレッドまたはコアが大幅に遅れ、他のスレッドまたはコアが高速かつ効率的に実行されている極端な状況では、ロックがない限り、実行(またはメモリアクセス)の順序が逆になる可能性があると想像できます。

4

2 に答える 2

2

正しく機能しているマルチプロセッサシステムでは、擬似コードは安全だと思います。C ++コンパイラは 、安全であることが証明されない限り、正しい値を受け取るCreateThread()前にへの呼び出しを生成することはできません。sharedVariableシングルスレッドコードは、完全に並べ替えられていない線形実行パスと同等に実行されることが保証されています。変数の割り当ての前にスレッドの作成を「タイムワープ」するシステムは、深刻に壊れています。

sharedVariableこの場合、揮発性として宣言しても何の役にも立たないと思います。

于 2010-02-11T16:52:35.083 に答える
1

あなたの例を考えると、 Javaを使用していた場合、答えは「いいえ」になります。Java では、割り当て操作が完了する前に、スレッドが生成して値を読み取ることはできません。 他の言語では、これは別の話かもしれません。

「複数のスレッド間で共有される変数 (オブジェクトのインスタンス変数など) には、long と double を除くすべてのデータ型の Java 言語仕様によってアトミックな割り当てが保証されています...メソッドが単一の変数アクセスまたは割り当てのみで構成されている場合、スレッドセーフのために同期化する必要があり、パフォーマンスのためにそうしないすべての理由があります。」 参照

doubleorlongが宣言されている場合volatile、割り当てがアトミック操作であることも保証されます。

更新: あなたの例は、Java で動作するように C++ でも動作します。理論的には、Out of Order Execution を使用しても、スレッドの生成が割り当ての前に開始または完了する方法はありません。

あなたの例は非常に具体的であり、それ以外の場合は、共有リソースが適切に保護されていることを確認することをお勧めします。新しい C++ 標準には多くのアトミックな要素が含まれているため、変数をアトミックとして宣言すると、割り当て操作はロックする必要なくすべてのスレッドに表示されます。CAS (比較して設定) は、次善の策です。

于 2010-02-11T03:26:44.893 に答える