수색…


소개

Ada에서 생산자 - 소비자 패턴이 어떻게 구현되는지 보여줍니다.

통사론

  • 함수 Scalar ' Image (인수 : Scalar'Base) 반환 문자열;
  • 작업 Task_Name;
  • 작업 Task_Name은 항목 끝입니다.
  • 태스크 본문 Task_Name은 선언입니다 begin 코드 종료;
  • entry entry_Name;
  • Entry_Name을 수락하십시오;
  • 출구;

비고

예제 모두 적절한 작업 종료를 보장 해야 합니다.

동기화 된 버퍼 사용

with Ada.Containers.Synchronized_Queue_Interfaces;
with Ada.Containers.Unbounded_Synchronized_Queues;
with Ada.Text_IO;

procedure Producer_Consumer_V1 is
   type Work_Item is range 1 .. 100;

   package Work_Item_Queue_Interfaces is
     new Ada.Containers.Synchronized_Queue_Interfaces
           (Element_Type => Work_Item);

   package Work_Item_Queues is
     new Ada.Containers.Unbounded_Synchronized_Queues
           (Queue_Interfaces => Work_Item_Queue_Interfaces);

   Queue : Work_Item_Queues.Queue;

   task type Producer;
   task type Consumer;

   Producers : array (1 .. 1)  of Producer;
   Consumers : array (1 .. 10) of Consumer;

   task body Producer is
   begin
      for Item in Work_Item loop
         Queue.Enqueue (New_Item => Item);
      end loop;
   end Producer;

   task body Consumer is
      Item : Work_Item;
   begin
      loop
         Queue.Dequeue (Element => Item);
         Ada.Text_IO.Put_Line (Work_Item'Image (Item));
      end loop;
   end Consumer;

begin
   null;
end Producer_Consumer_V1;

나는 여기서 게으르다. 모든 작업 항목이 소비되면 소비자 작업이 제대로 종료되지 않는다.

Ada Rendezvous 메커니즘을 사용한 생산자 - 소비자 패턴

동기식 생산자 - 소비자 솔루션은 소비자가 생산자가 작성한 모든 데이터 항목을 정확히 한 번씩 읽도록 보장합니다. 비동기 솔루션을 사용하면 소비자가 제작자의 출력을 샘플링 할 수 있습니다. 소비자가 생산되는 것보다 빠르게 데이터를 소비하거나 소비자가 생산 된 것보다 느리게 데이터를 소비합니다. 샘플링을 통해 소비자는 현재 사용 가능한 데이터를 처리 할 수 ​​있습니다. 이 데이터는 생성 된 데이터의 샘플링 일 수도 있고 이미 소비 된 데이터 일 수도 있습니다.

------------------------------------------------------------------
-- synchronous PC using Rendezvous --
------------------------------------------------------------------
with Ada.Text_IO; use Ada.Text_IO;

procedure PC_Rendezvous is
   task Producer;
   task Consumer is
      entry Buf(Item : in Integer);
   end Consumer;
   task body Producer is
   begin
      for I in 1..10 loop
         Put_Line("Producer writing" & Integer'Image(I));
         Consumer.Buf(I);
      end loop;
   end Producer;
   task body Consumer is
      Temp : Integer;
   begin
      loop
         select
            accept Buf(Item : in Integer) do
               temp := Item;
            end;
            Put_Line("Consumer read" & Integer'Image(Temp));
         or
            terminate;
         end select;
      end loop;
   end Consumer;

begin
   null;
end PC_Rendezvous;

샘플링 소비자가있는 프로듀서 - 소비자

이 예제에서는 주 프로 시저를 생산자 작업으로 사용합니다. Ada에서 main 프로시 저는 항상 프로그램의 다른 모든 태스크와 별도의 태스크에서 실행됩니다. 최소 예제를 참조하십시오 .

------------------------------------------------------------------
-- Sampling Consumer --
------------------------------------------------------------------
with Ada.Text_IO; use Ada.Text_IO;

procedure Sampling_PC is
   protected Buf is
      procedure Write(Item : in Integer);
      function Read return Integer;
      procedure Set_Done;
      function Get_Done return Boolean;
   private
      Value : Integer := Integer'First;
      Is_Done : Boolean := False;
   end Buf;
   protected body Buf is
      procedure Write(Item : in Integer) is
      begin
         Value := Item;
      end Write;
      function Read return Integer is
      begin
         return Value;
      end Read;
      procedure Set_Done is
      begin
         Is_Done := True;
      end Set_Done;
      function Get_Done return Boolean is
      begin
         return Is_Done;
      end Get_Done;
   end Buf;

   task Consumer;
   task body Consumer is
   begin
      while not Buf.Get_Done loop
          Put_Line("Consumer read" & Integer'Image(Buf.Read));
      end loop;
   end Consumer;

begin
   for I in 1..10 loop
     Put_Line("Producer writing" & Integer'Image(I));
     Buf.Write(I);
   end loop;
   Buf.Set_Done;
end Sampling_PC;

같은 버퍼를 공유하는 여러 제작자와 소비자

이 예제는 동일한 버퍼를 공유하는 여러 제작자와 소비자를 보여줍니다. Ada의 보호 된 항목은 대기중인 작업을 처리하기 위해 대기열을 구현합니다. 기본 큐 정책은 First In First Out입니다.

------------------------------------------------------------------
-- Multiple producers and consumers sharing the same buffer --
------------------------------------------------------------------
with Ada.Text_IO; use Ada.Text_Io;

procedure N_Prod_Con is
   protected Buffer is
      Entry Write(Item : in Integer);
      Entry Read(Item : Out Integer);
   private
      Value  : Integer := Integer'Last;
      Is_New : Boolean := False;
   end Buffer;
   protected body Buffer is
      Entry Write(Item : in Integer) when not Is_New is
      begin
         Value := Item;
         Is_New := True;
      end Write;
      Entry Read(Item : out Integer) when Is_New is
      begin
         Item := Value;
         Is_New := False;
      end Read;
   end Buffer;

   task type Producers(Id : Positive) is
      Entry Stop;
   end Producers;
   task body Producers is
      Num : Positive := 1;
   begin
      loop
         select
            accept Stop;
            exit;
         or
            delay 0.0001;
         end select;
         Put_Line("Producer" & Integer'Image(Id) & " writing" & Integer'Image(Num));
         Buffer.Write(Num);
         Num := Num + 1;
      end loop;
   end Producers;

   task type Consumers(Id : Positive) is
      Entry Stop;
   end Consumers;

   task body Consumers is
      Num : Integer;
   begin
      loop
         select
            accept stop;
            exit;
         or
            delay 0.0001;
         end select;
         Buffer.Read(Num);
         Put_Line("Consumer" & Integer'Image(ID) & " read" & Integer'Image(Num));
      end loop;
   end Consumers;
   P1 : Producers(1);
   P2 : Producers(2);
   P3 : Producers(3);
   C1 : Consumers(1);
   C2 : Consumers(2);
   C3 : Consumers(3);
begin
   delay 0.2;
   P1.Stop;
   P2.Stop;
   P3.Stop;
   C1.Stop;
   C2.Stop;
   C3.Stop;
end N_Prod_Con;


Modified text is an extract of the original Stack Overflow Documentation
아래 라이선스 CC BY-SA 3.0
와 제휴하지 않음 Stack Overflow