Temat:
Realizacja bufora cyklicznego w języku Ada z wykorzystaniem obiektu chronionego.Bufor cykliczny to prosta struktura danych zrealizowana w przypadku tego programu na tablicy pięcioelementowej, gdzie dane dodawane są i pobierane zgodnie z indeksami wskaźników (w programie GetIndex i PutIndex). Obiekt chroniony zapewnia wzajemne wykluczanie dostępu do zasobów dwóch współbieżnie działających zadań (producenta i konsumenta). Modyfikowanie danych w tablicy dokonuje się za pomocą dwóch instrukcji entry wywoływanych z obu zadań w losowych chwilach czasu. Instrukcje te zapewniają nie tylko synchronizację zadań, ale także zawieszenie zadania, jeśli nie jest spełniony warunek zapisany instrukcją when. Zadanie zostaje odwieszone, gdy warunek ponownie zostanie spełniony.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 | with Ada.Text_Io; use Ada.Text_Io; with Ada.Numerics.Discrete_Random; procedure Cyclic_Buffer is type Buffer is array (Integer range <>) of Integer; Size : Integer:=5; subtype Wait is Integer range 0..5; package Draw is new Ada.Numerics.Discrete_Random(Wait); use Draw; G : Generator; protected Protected_Buffer is entry Add(I : in Integer); entry Take(I : out Integer); private B : Buffer(1..Size); Counter : Integer:=0; GetIndex : Integer:=1; PutIndex : Integer:=1; end Protected_Buffer; task Producer; task Consumer; protected body Protected_Buffer is entry Add(I : in Integer) when Counter < Size is begin B(PutIndex) := I; PutIndex := PutIndex mod Size + 1; Counter := Counter + 1; end Add; entry Take(I : out Integer) when Counter > 0 is begin I:=B(GetIndex); GetIndex := GetIndex mod Size + 1; Counter := Counter - 1; end Take; end Protected_Buffer; task body Consumer is Cons_Delay_Time : Integer; begin loop Reset(G); Cons_Delay_Time:=Integer(Random(G)); delay Duration(1.3*Float(Cons_Delay_Time)); Protected_Buffer.Take(Cons_Delay_Time); Put_Line("Consumer : Taking "&Cons_Delay_Time'Img); delay 0.15; end loop; end Consumer; task body Producer is Prod_Delay_Time : Integer; begin loop Reset(G); Prod_Delay_Time := Integer(Random(G)); delay Duration(Prod_Delay_Time); Protected_Buffer.Add(Prod_Delay_Time); Put_Line("Producer : Adding "&Prod_Delay_Time'Img); delay 0.15; end loop; end Producer; begin null; end Cyclic_Buffer; |
Komentarze:
[11 - 14] Deklaracje generatora liczb pseudolosowych, który odpowiada za losowe czasy opóźnienia w działaniu obu zadań (od 0 do 5 sek).
[27 - 28] Uruchomienie wykonywania zadań
[55] Opóźnienie wykonywania zadania zależne od wylosowanej liczby
[56] Pobranie z bufora wartości do zmiennej lokalnej
[77] Pusta instrukcja programu - wszystkie instrukcje wykonują się w dwóch współbieżnych zadaniach
Kompilator: Ideone.com
Brak komentarzy:
Prześlij komentarz