4

次の疑似コードを見てください。

boolean blocked[2];
int turn;
void P(int id) {
      while(true) {
             blocked[id] = true;
             while(turn != id) {
                    while(blocked[1-id])
                    /* do nothing */;
                    turn = id;
             }
             /* critical section */
             blocked[id] = false;
             /* remainder */
      }
}
void main() {
      blocked[0] = false;
      blocked[1] = false;
      turn = 0;
      parbegin(P(0), P(1)); //RUN P0 and P1 parallel
}

上記のコードを使用して、単純な相互除外ソリューションを実装できると思いました。しかし、それは機能していません。誰かが理由を知っていますか?

どんな助けでも本当に感謝します!

4

6 に答える 6

5

この例では、次の理由により、相互排除は保証されません。

次の状況から始めます。

blocked = {false, false};
turn = 0;

P1 が実行され、スキップされます

  blocked[id] = false; // Not yet executed.

現在の状況は次のとおりです。

blocked {false, true}
turn = 0;

ここで P0 が実行されます。2 番目の while ループを通過し、クリティカル セクションを実行する準備が整います。そして、P1 が実行されると、ターンを 1 に設定し、クリティカル セクションを実行する準備も整います。

ところで、この方法はもともとハイマンによって発明されました。彼は 1966 年に Acm の通信にそれを送った

于 2009-05-18T09:06:11.750 に答える
2

相互排除は、次の理由で保証されていないこの例に含まれています。

次の状況から始めます。

turn= 1;
blocked = {false, false};

実行は次のように実行されます。

P0: while (true) {
P0:   blocked[0] = true;
P0:   while (turn != 0) {
P0:     while (blocked[1]) {
P0:     }
P1: while (true) {
P1:   blocked[1] = true;
P1:   while (turn != 1) {
P1:   }
P1:   criticalSection(P1);
P0:     turn = 0;
P0:   while (turn != 0)
P0:   }
P0:   critcalSection(P0);
于 2009-12-07T20:14:29.540 に答える
0

これは宿題ですか、それとも組み込みプラットフォームですか? pthreads または Win32 (関連する) 同期プリミティブを使用できない理由はありますか?

于 2009-01-04T22:02:55.217 に答える
-1

特にマルチプロセッサ(またはマルチコア)環境では、このように同時実行を実装することはできません。コア/プロセッサが異なれば、キャッシュも異なります。これらのキャッシュはコヒーレントではない可能性があります。以下の擬似コードは、示されている順序で実行され、結果が示されます。

get blocked[0] -> false   // cpu 0
set blocked[0] = true     // cpu 1 (stored in CPU 1's L1 cache)
get blocked[0] -> false   // cpu 0 (retrieved from CPU 0's L1 cache)
get glocked[0] -> false   // cpu 2 (retrieved from main memory)

同時実行を実装するには、ハードウェアの知識が必要です。

于 2009-01-04T20:03:57.017 に答える
-1

コンパイラは、「空の」while ループを最適化した可能性があります。変数を volatile として宣言すると役立つ場合がありますが、マルチプロセッサ システムでは十分であるとは限りません。

于 2009-01-04T20:40:33.807 に答える
-1

ブロックされたと宣言し、揮発性として回転する必要があるかもしれませんが、プログラミング言語を指定しないと知る方法はありません.

于 2009-01-04T19:19:06.310 に答える