2016-12-14 12 views
0

classical producer-consumer problemには、共有バッファがいっぱいになるとプロデューサが待機し、共有バッファが空のときにコンシューマが待機します。私たちは空のセマフォと完全なセマフォ(両方のセマフォをカウントする)に対してsem_waitとsem_postを使って互いに同期する2つのposixスレッド、1つのプロデューサと他の作業者を持っています。したがって、生産者 - 消費者コードのセマフォ実装は、以下のようにのように見える:プロデューサー()と消費者()を推定デッドロックを防ぐための例外処理を持つC++プロデューサ - コンシューマ

procedure producer() { 
    while (true) { 
     item = produceItem(); 
     down(emptyCount); 
      down(buffer_mutex); 
       putItemIntoBuffer(item); 
      up(buffer_mutex); 
     up(fillCount); 
    } 
} 

procedure consumer() { 
    while (true) { 
     down(fillCount); 
      down(buffer_mutex); 
       item = removeItemFromBuffer(); 
      up(buffer_mutex); 
     up(emptyCount); 
     consumeItem(item); 
    } 
} 

produceItem又はconsumeItemは、実行時例外が対向したときに何が起こるか、独立した同時スレッドで実行されています両方のスレッドが正常に出てくるように、スレッドは例外を正常に処理します。 状況をうまく処理するためにtry-catchをどこに置くべきですか?

+0

あなたが予想される例外の本質とは何ですか?プロデューサが共有バッファへの書き込みに失敗した場合、プロデューサは例外を処理する必要があり、消費者は例外を認識すべきではありません。コンシューマが共有バッファからの読み込みに失敗した場合、コンシューマは例外を処理する必要があり、プロデューサは例外を認識すべきではありません。 –

+0

@JimRogers consumeItem(item)および/またはproduceItem()は例外 –

+0

に直面する可能性がありますが、2つのスレッド間の唯一のインターフェイスはバッファです。プロデューサが例外に遭遇した場合、コンシューマはそれが例外から回復するのを待つ。同様に、消費者が例外に遭遇した場合、プロデューサは消費者が例外から回復するのを待つ。プロデューサまたはコンシューマのいずれかが例外から回復しないことを心配する場合は、各スレッドのバッファへのアクセス待ちにタイムアウトを適用する必要があります。 –

答えて

0

私は自分のマルチスレッドの大部分をAdaを使って行います。次のAdaの例は、コンディション変数の待機にタイムアウトを適用することによって、コンシューマが非応答プロデューサを処理し、プロデューサが非応答コンシューマを処理する方法を示しています。

------------------------------------------------------------------ 
-- Producer-Consumer Package -- 
------------------------------------------------------------------ 
with Ada.Text_IO; use Ada.Text_IO; 

procedure Protected_Producer_Consumer is 
    protected Buffer is 
     entry Put(Item : in Integer); 
     entry Get(Item : out Integer); 
    private 
     Value : Integer := Integer'First; 
     Is_New : Boolean := False; 
    end Buffer; 

    protected body Buffer is 
     entry Put(Item : in Integer) when not Is_New is 
     begin 
     Value := Item; 
     Is_New := True; 
     end Put; 
     entry Get(Item : out Integer) when Is_New is 
     begin 
     Item := Value; 
     Is_New := False; 
     end Get; 
    end Buffer; 

    task producer; 
    task body producer is 
     Wait_Limit : constant Natural := 5; 
     Written : Boolean := False; 
    begin 
     for value in 1..15 loop 
     Written := False; 
     for try in 1..Wait_Limit loop 
      Select 
       Buffer.Put(Value); 
       Written := True; 
      or 
       delay 0.5; 
      end select; 
      exit when Written; 
     end loop; 
     if not Written then 
      Put_Line("Producer terminating. Consumer not responding."); 
      exit; 
     end if; 
     end loop; 
    end producer; 

    task consumer; 
    task body consumer is 
     Wait_Limit : Natural := 5; 
     Value_Read : Boolean; 
     The_Value : Integer; 
    begin 
     Loop 
     Value_Read := False; 
     for try in 1..Wait_Limit loop 
      select 
       Buffer.Get(The_Value); 
       Value_Read := True; 
       Put_Line("Consumer read value: " & Integer'Image(The_Value)); 
      or 
       delay 0.5; 
      end select; 
      exit when Value_Read; 
     end loop; 
     if not Value_Read then 
      Put_Line("Consumer terminating. Producer not responding."); 
      exit; 
     end if; 
     end loop; 
    end Consumer; 

begin 
    null; 
end Protected_Producer_Consumer; 

上記の例のバッファなどのAdaで保護されたオブジェクトは、自動的に相互排除を提供します。上の例では、BufferオブジェクトにPutとGetの2つのエントリがあります。 Putエントリは、バッファ内部変数Is_NewがFalseの場合にのみ実行できます。 Getエントリは、バッファの内部変数Is_NewがTrueの場合にのみ実行できます。

Producerタスク(C++のスレッドに似ています)には、変数「値」を最初の1に、次に2までを15まで設定する外部ループが含まれています。バッファはWait_Limit回までバッファリングされます。毎回プロデューサが0.5秒間タイマーを設定し、成功しなかった場合は再び試行します。プロデューサがWait_Limitに失敗すると、エラーメッセージが書き込まれ、終了します。

消費者の行動はプロデューサに似ています。 Getエントリを呼び出してBufferから値を読み取ります。また、試行ごとに0.5秒待ってから、Wait_Limitの連続した失敗からバッファから値を読み取った後に終了します。

このプログラムの出力は次のとおりです。

Consumer read value: 1 
Consumer read value: 2 
Consumer read value: 3 
Consumer read value: 4 
Consumer read value: 5 
Consumer read value: 6 
Consumer read value: 7 
Consumer read value: 8 
Consumer read value: 9 
Consumer read value: 10 
Consumer read value: 11 
Consumer read value: 12 
Consumer read value: 13 
Consumer read value: 14 
Consumer read value: 15 
Consumer terminating. Producer not responding. 
関連する問題