This assignment, and I was asked to implement Semaphore in Hell as a description below.
However, I implemented Semaphore.adband named this Semaphore in producerconsumer_sem.adbwhich I created.
I get some conclusion, which is next.
I'm not sure my semaphore initialization is correct S: CountingSemaphore(1,1);.
I don’t know where I call S.waitand S.Signal, now I accidentally called S.waitbefore Producer put the item in the buffer X := I;and S.Signalafter X := I;, Is this correct?
The problem of producer and consumer The program producerconsumer.adbimplements an unreliable implementation of the problem of producer and consumer, where data is likely to be lost. In the following way, you will use three different communication mechanisms to achieve a reliable implementation of the producer-consumer problem.
Semaphore
Ada does not directly provide library functions for the semaphore. However, semaphores can be implemented using a protected object. Creating the specification of the Semaphore package in the Semaphores.ads file and the corresponding package body in the file Semaphores.adbthat implements the counting semaphore. Skeletons for the package are available on the course page.
- . producerconsumer.adb producerconsumer_sem.adb. , producerconsumer_sem.adb.
with Semaphores; use Semaphores;
:
: 1 1 1 2 2 3 4 4 5 6 6 7 7 8 9 9 9 10 11 11 11 12 12 13 13 13 14 15 15 16 16 17 18 18 18 19 20 20 21 21 22 22 23 24 24 24 24 25 25 26 27 27 28 29 29 30 30 31 31 32 32 33 33 33 34 35 35 35 36 36 37 37 37 38 38 38 39 40 40 40
package Semaphores is
protected type CountingSemaphore(Max: Natural; Initial: Natural) is
entry Wait;
entry Signal;
private
Count : Natural := Initial;
MaxCount : Natural := Max;
end CountingSemaphore;
end Semaphores;
Semaphores.adb.
package body Semaphores is
protected body CountingSemaphore is
entry Wait when Count > 0 is
begin
Count := Count - 1;
end Wait;
entry Signal when Count < MaxCount is
begin
Count := Count + 1;
end Signal;
end CountingSemaphore;
end Semaphores;
producerconsumer_sem.adb
with Ada.Text_IO;
use Ada.Text_IO;
with Ada.Real_Time;
use Ada.Real_Time;
with Ada.Numerics.Discrete_Random;
with Semaphores;
use Semaphores;
procedure ProducerConsumer_sem is
X : Integer;
N : constant Integer := 40;
S: CountingSemaphore(1,1);
pragma Volatile(X);
subtype Delay_Interval is Integer range 50..250;
package Random_Delay is new Ada.Numerics.Discrete_Random
(Delay_Interval);
use Random_Delay;
G : Generator;
task Producer;
task Consumer;
task body Producer is
Next : Time;
begin
Next := Clock;
for I in 1..N loop
S.Wait;
X := I;
S.Signal;
Next := Next + Milliseconds(Random(G));
Put_Line(Integer'Image(X));
delay until Next;
end loop;
end;
task body Consumer is
Next : Time;
begin
Next := Clock;
for I in 1..N loop
S.Wait;
Put_Line(Integer'Image(X));
S.Signal;
Next := Next + Milliseconds(Random(G));
delay until Next;
end loop;
end;
begin
null;
end ProducerConsumer_sem;