3

最近、私はこの問題を最初のリーダライタの問題とよく似ています。「セマフォを使用してNプロセスバリアを実装する」への変更

Implementing an N process barrier using semaphores

私はそれを再利用し、正常に動作することができることを確認しましたし、それを修正しようとしています。

n = the number of threads 
count = 0 
mutex = Semaphore(1) 
barrier = Semaphore(0) 


mutex.wait() 
count = count + 1 
if (count == n){ barrier.signal()} 
mutex.signal() 

barrier.wait() 

mutex.wait() 
count=count-1 
barrier.signal() 
if(count==0){ barrier.wait()} 
mutex.signal() 

これは間違いありませんか?

私が検出しなかったいくつかの間違いが存在するかどうかは疑問です。

答えて

1

あなたの疑似コードは、バリアを初期の状態に戻します。無意味な提案:

より読みやすい私見で

barrier.signal() 
if(count==0){ barrier.wait()} 

を交換

if(count!=0){ barrier.signal()} //if anyone left pending barrier, release it 

しかし、道に落とし穴があるかもしれない、バリアが再利用されます。説明された障壁には、2つの状態があります。

  1. すべてのスレッドがすべて保留になるまで停止します。
  2. 再開各スレッドにそれらのすべてが

それらを混合に対する保護はありません実行しているまで:いくつかのスレッドが再開され、他はすでに再び最初のステージを襲っているがを。たとえば、いくつかのことを行い、バリアを同期させるスレッドがたくさんあります。各スレッド本体は次のようになります。

while (!exit_condition) { 
    do_some_stuff(); 
    pend_barrier(); // implementation from current question 
} 

プログラマが期待し、do_some_stuff()のための呼び出しの数がすべてのスレッドで同じになります。タイミングによっては何が起きるかもしれません。バリアから解放された最初のスレッドは、すべてのスレッドがバリアを去る前に計算を完了しますので、2度目は保留状態に戻ります。その結果、彼は現在のバリアリリースの反復で他のスレッドと一緒にリリースされ、少なくともdo_some_stuff()をもう1回呼び出すでしょう。

+0

ありがとうございます!もし私が別のセマフォー "size = semaphore(n)"とsize.wait()を使ってエントリーをコントロールするとどうなりますか? "if(count == 0){for(i = 1〜n){size.signal()} "を使用してリフレッシュします。そうですか? –

+1

私はそれがうまくいくはずだと思います。 –

関連する問題