ada
생산자 - 소비자 패턴 구현
수색…
소개
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