私が大学で取ったコースで覚えているのは、競合状態の私のお気に入りの例の 1 つは、単純なmain()
メソッドが 2 つのスレッドを開始し、そのうちの 1 つは共有 (グローバル) 変数を 1 ずつインクリメントし、もう 1 つはそれをデクリメントするというものでした。擬似コード:
static int i = 10;
main() {
new Thread(thread_run1).start();
new Thread(thread_run2).start();
waitForThreads();
print("The value of i: " + i);
}
thread_run1 {
i++;
}
thread_run2 {
i--;
}
次に、教授はi
、100 万億回実行した後の の値を尋ねました。(本質的に 10 以外になるとしたら。) マルチスレッド システムに慣れていない学生は、100% の確率で、このprint()
ステートメントは常にi
10 と報告されると答えました。
私たちの教授は、各インクリメント/デクリメント ステートメントが実際には 3 つのステートメントとして (アセンブリに) コンパイルされたことを示したため、これは実際には正しくありません。
1: move value of 'i' into register x
2: add 1 to value in register x
3: move value of register x into 'i'
したがって、 の値はi
9、10、または 11 になる可能性があります (詳細には触れません)。
私の質問:
物理レジスタのセットがプロセッサ固有であることは、私の理解でした(そうですか?)。デュアル CPU マシンで作業する場合 (デュアルコアとデュアル CPU の違いに注意してください)、各 CPU には独自の物理レジスタ セットがありますか? 私は答えがイエスだと思っていました。
シングル CPU (マルチスレッド) マシンでは、コンテキスト切り替えにより、各スレッドが独自の仮想レジスタ セットを持つことができます。デュアル CPU マシンには 2 つの物理的なレジスタ セットがあるため、競合状態が発生する可能性がさらに高まるのではないでしょうか。 CPUマシン?(コンテキストスイッチごとにレジスタの状態を退避・復帰することを参考にした仮想同時動作。)
より具体的に言えば、これを 8 CPU マシンで実行した場合、各 CPU に 1 つのスレッドがあり、競合状態は解消されますか? この例を拡張して、各 CPU に 4 つのコアを持つデュアル CPU マシンで 8 つのスレッドを使用する場合、競合状態の可能性は増加しますか、それとも減少しますか? オペレーティング システムは、アセンブリ命令が 2 つの異なる CPU で同時に実行されるのをどのように防いでいますか?step 3