1

バリアは、プロセスのセットがグローバルに同期する同期構造です。つまり、セット内の各プロセスがバリアに到着し、他のすべてのプロセスが到着するのを待ってから、すべてのプロセスがバリアを離れます。セット内のプロセスの数を3とし、Sを通常のPおよびV関数を持つバイナリセマフォとします。左側に行番号が示されているバリアの次のC実装について考えてみます。

void barrier (void) {    
    1: P(S);
    2: process_arrived++;
    3: V(S);
    4: while (process_arrived !=3);
    5: P(S);
    6: process_left++;
    7: if (process_left==3) 
       {
         8: process_arrived = 0;
         9: process_left = 0;
    10: }
    11: V(S);
 }

変数process_arrivedとprocess_leftはすべてのプロセスで共有され、ゼロに初期化されます。並行プログラムでは、3つのプロセスすべてが、グローバルに同期する必要があるときにバリア関数を呼び出します。

上記の実装は機能しますか?2つのバリア呼び出しがすぐに連続して使用されると、デッドロックにつながる可能性があると思います。バリアに入る最初のプロセスは、process_arrivedがゼロになるまで待機してからP(S)の実行に進むためです。

4

2 に答える 2

1

3つのプロセスがあると言われています。P1、P2、P3とします。すべてのプロセスがバリアに到達します。つまり、コードの最初のセクションが完了します。したがって、process_arrived = 3です。ここで、P1が実行を継続し、バリアを離れてprocess_left=1になると仮定します。ここで、P1が再びバリア機能をすぐに呼び出すと仮定します。この段階では、process_arrived=4です。P1は待機します。すぐにP2がバリアを離れ、process_left=2になります。これで、P3はprocess_left=3になるバリアを離れます。「If」条件が真であり、process_arrivedおよびprocess_leftが0にリセットされます。P1が待機していることがわかります。この段階では、P2がバリア機能を呼び出すと想定しているため、process_arrived=1で待機します。P3はバリア関数を呼び出すため、process_arrived=2になります。すべてのプロセスが障壁に達しましたが、process_arrived = 2以降、すべてのプロセスが待機し続けます。したがって、デッドロック。

于 2014-12-29T13:15:17.833 に答える
0

うーん...3つのスレッドとバイナリセマフォのみに制限されているので、3つのセマフォA、B、Cを使用してこれを試してみたくなるでしょう。Aはprocess_arrivedカウントへのアクセスを制御し、BとCは最初と2番目のスレッドが待機するためのものですの上。Aは1に初期化され、BとCは0に初期化されます。スレッド1はAを取得するため、2と3が入るのを防ぎます。process_arrivedをオンにすると、スレッド1はprocess_arrivedを含み、Aを解放してBを待機します。スレッド2はAを取得し、スイッチはそれをprocess_arrivedを含み、切り替えてAを解放し、Cを待機させます。スレッド3はAを取得し、スイッチはシグナルB、シグナルC、process_arrivedを0、シグナルAに設定し、続行します。

スレッド1と2は、3が信号を送るまでBとCを通過できません。B / Cが3によって信号を送られると、1/2は実行できますが、3がAを解放するまでループバックしてバリアに入ることができません。その時点で、バリアは再びバリアとして機能する正しい状態になります-Aのカウントは1、BとCはゼロで、process_arrivedはゼロです。

于 2011-11-04T20:37:47.180 に答える