WOJSKOWA AKADEMIA TECHNICZNA
Laboratorium z przedmiotu
Programowanie Współbieżne
SPRAWOZDANIE
Projekt - Kasy biletowe na dworcu PKP
Piotr Rusinowski g. I7X6S1 |
Prowadzący: mgr inż. Marcin Dąbkiewicz |
Data wykonania: 05.06.2009 |
Ocena: |
TREŚĆ ZADANIA
Zaprojektuj system kas biletowych na dworcu PKP. Dostępne są trzy kasy, do których klienci podchodzą pojedynczo z dwóch kolejek. Klient przed podejściem do kasy pobiera numerek wskazujący na nią. Jeśli kasa w danej chwili jest zajęta to czeka ze swoim numerkiem, aż się ona zwolni. W jednej kasie w danej chwili może przebywać tylko jeden klient.
ANALIZA ZADANIA
Mamy 3 kasy, a więc potrzebujemy 3 obiekty(odpowiednio: Kasa1, Kasa2, Kasa3). Liczbę klientów ustalam na początku programu wpisując ilość procesów których chce by się wykonywały(liczba ta ma być mniejsza równa 24 ). Klienci ustawieni są w dwóch kolejkach do których są przydzielani losowo( Kolejka 1 i Kolejka 2). Klient po wyjściu z kolejki pobiera swój numerek i przechodzi do poczekalni. Jeśli kasa której numerek wybrał jest wolna to podchodzi do niej i zostaje obsłużony. Kasa wtedy zmienia swój status z WOLNA na ZAJETA. Po odejściu od kasy klient wychodzi tą samą drogą którą przyszedł.
ZASTOSOWANE MECHANIZMY WSPÓŁBIEŻNOŚCI
Do wykonania pierwszej wersji zadania wykorzystałem Semafory binarne dołączone do programu w bibliotece SEM 95. Do drugiej wersji zadania wykorzystałem mechanizm spotkań.
SEKCJA KRYTYCZNA
Sekcja krytyczna kasy pierwszej
PB(Kas1);
czas:=randomint(15);
ONumerek(14,52,Y,X,Lp);
delay(duration(1));
if Numer<24 then
TLO.Rys_napisy(robo_Y+Numer,robo_X," ",white);
TLO.Rys_napisy(robo_Y+Numer,robo_X+1," ",white);
for i in 1..10 loop
TLO.Rys_klient(robo_Y+Numer,robo_X-i,Numer);
delay(duration(0.05));
TLO.Rys_napisy(robo_Y+Numer,robo_X-i," ",white);
end loop;
end if;
TLO.Rys_napisy(Y,X," ZAJETA",green);
TLO.Rys_klient(Y,X+10,Numer);
delay(duration(czas));
TLO.Rys_napisy(Y,X," WOLNA ",white);
TLO.Rys_napisy(Y,X+10," ",white);
TLO.Rys_napisy(Y+1,X," ",white);
delay(duration(1));
VB(Kas1);
Sekcja krytyczna kasy drugiej
PB(Kas2);
czas:=randomint(15);
ONumerek(14,52,Y,X,Lp);
delay(duration(1));
if Numer<24 then
TLO.Rys_napisy(robo_Y+Numer,robo_X," ",white);
TLO.Rys_napisy(robo_Y+Numer,robo_X+1," ",white);
for i in 1..10 loop
TLO.Rys_klient(robo_Y+Numer,robo_X-i,Numer);
delay(duration(0.05));
TLO.Rys_napisy(robo_Y+Numer,robo_X-i," ",white);
end loop;
end if;
TLO.Rys_napisy(Y,X," ZAJETA",green);
TLO.Rys_klient(Y,X+10,Numer);
delay(duration(czas));
TLO.Rys_napisy(Y,X," WOLNA ",white);
TLO.Rys_napisy(Y,X+10," ",white);
TLO.Rys_napisy(Y+1,X," ",white);
delay(duration(1));
VB(Kas2);
Sekcja krytyczna kasy trzeciej
PB(Kas1);
czas:=randomint(15);
ONumerek(14,52,Y,X,Lp);
delay(duration(1));
if Numer<24 then
TLO.Rys_napisy(robo_Y+Numer,robo_X," ",white);
TLO.Rys_napisy(robo_Y+Numer,robo_X+1," ",white);
for i in 1..10 loop
TLO.Rys_klient(robo_Y+Numer,robo_X-i,Numer);
delay(duration(0.05));
TLO.Rys_napisy(robo_Y+Numer,robo_X-i," ",white);
end loop;
end if;
TLO.Rys_napisy(Y,X," ZAJETA",green);
TLO.Rys_klient(Y,X+10,Numer);
delay(duration(czas));
TLO.Rys_napisy(Y,X," WOLNA ",white);
TLO.Rys_napisy(Y,X+10," ",white);
TLO.Rys_napisy(Y+1,X," ",white);
delay(duration(1));
VB(Kas1);
Sekcja krytyczna pierwszej części pobierania numerka
PB(Nr);
TLO.Rys_klient(Y,X+2,Lp);
TLO.Rys_napisy(Y-2,X,"N ",green);
TabNr(Lpobranych+1):=Kasa*100+Lodczytanych;
Numerek:=TabNr(Lpobranych+1);
Lpobranych:=Lpobranych+1;
Lodczytanych:=(Lodczytanych+1)mod 100;
delay(duration(0.1));
TLO.Rys_napisy(Y-2,X," ",white);
TLO.Rys_napisy(Y,X+2," ",white);
VB(Nr);
Sekcja krytyczna drugiej części pobierania numerka
PB(Nr);
TLO.Rys_napisy(pozy+1,pozx,"Nr: ",red);
temp:=1;
while (integer(TabNr(temp)/100)) /= Lp loop
temp:=temp+1;
end loop;
TLO.Rys_numer(pozy+1,pozx+4,TabNr(temp));
delay(duration(0.2));
for i in temp..Lpobranych loop
TabNr(i):=TabNr(i+1);
end loop;
Lpobranych:=Lpobranych - 1;
VB(Nr);
STRUKTURA PROGRAMU
with ada.text_IO; use ada.text_IO;
with ada.integer_text_IO; use ada.integer_text_IO;
with randompackage; use randompackage;
with WinConsoleEx; use WinConsoleEx;
with Sem95; use Sem95;
--PROCEDURA DWORZECSEM---GŁÓWNA PROCEDURA PROGRAMU---
procedure DworzecSem is
--DEKLARACJA TABLICY DO NAPISÓW-----
type napisy is array (1..7) of character;
--DEKLARACJA WARTOŚCI robo_X I robo_Y WYKORZYSTYWANYCH POŹNIEJ----
robo_X:integer :=42 ; robo_Y:integer :=2;
--DEKLARACJA LICZBY POBRAŃ I ODCZYTÓW----
Lpobranych: integer := 0;
Lodczytanych: integer:= 0;
temp: integer;
-- DEKLARACJA TABLICY NUMERÓW----
TabNr: array(1..100) of integer:=(others => 1000);
--DEKLARACJA SEMAFORÓW----
We1: Semafor_binarny(1);---DLA WEJŚCIA----
We2: Semafor_binarny(1);
Kas1: Semafor_binarny(1);---DLA KAS----
Kas2: Semafor_binarny(1);
Kas3: Semafor_binarny(1);
Nr : Semafor_binarny(1);---DLA NUMERÓW PROCESÓW----
-- WYŚWIETLANIE ------------------------------------------------------------
protected TLO is
entry Rys_budynek;
entry Rys_klient(Y: in integer; X: in integer; Numer: in integer);
entry Rys_napisy(Y: in integer; X: in integer; Napis: napisy ; Kolor: color);
entry Rys_numer(Y: in integer; X: in integer; Numer: in integer);
end TLO;
protected body TLO is
entry Rys_klient(Y: in integer; X: in integer; Numer: in integer) when True is
begin
text(white);
movecursor(Y,X);
Put("K("); Put(Numer,1) ; Put(")");
end Rys_klient;
entry Rys_numer(Y: in integer; X: in integer; Numer: in integer) when True is
begin
text(red);
movecursor(Y,X);
Put(Numer,1);
end Rys_numer;
entry Rys_napisy(Y: in integer; X: in integer; Napis: napisy ; Kolor: color ) when True is
begin
movecursor(Y,X);
text(Kolor);
for i in 1..7
loop
Put(Napis(i));
end loop;
end;
--RYSOWANIE TŁA--------------
entry Rys_budynek when True is
a:integer;
begin
NULL;
text(yellow);
movecursor(1,1);
Put("___________DWORZEC PKP - KASY BILETOWE___________|");
text(green);
movecursor(2,2);
Put("KASY BILETOWE");
movecursor(2,35);
Put("POCZEKALNIA");
text(yellow);
a:=3;
for i in 1..3
loop
Movecursor(a+0,1);
Put(" ________" );
Movecursor(a+1,1);
Put("| KASA "); Put(i,1); Put("|");
Movecursor(a+2,1);
Put("| |");
Movecursor(a+3,1);
Put("|________|");
a:=a+4;
end loop;
for i in 2..16
loop
movecursor(i,16);
Put("|");
end loop;
for i in 2..24
loop
movecursor(i,31);
Put("|");
end loop;
for i in 2..13
loop
movecursor(i,50);
Put("|");
end loop;
for i in 15..24
loop
movecursor(i,50);
Put("|");
end loop;
for i in 1..29
loop
movecursor(16,i);
Put("--");
end loop;
movecursor(13,51);
put("--");
movecursor(14,52);
put("/");
movecursor(15,51);
put("--");
movecursor(3,71);
put("KOLEJKA 1");
movecursor(4,73);
Put("------");
movecursor(6,73);
Put("------");
movecursor(10,71);
put("KOLEJKA 2");
movecursor(11,73);
Put("------");
movecursor(13,73);
Put("------");
Text(white);
end Rys_budynek;
end TLO;
--PROCES POBIERANIA NUMERKA ------------------------------------------
function PNumerek(Y: integer ; X: integer ; Lp: integer ; Kasa: integer) return integer is
Numerek: integer;
begin
PB(Nr); -----SEKCJA KRYTYCZNA
TLO.Rys_klient(Y,X+2,Lp);
TLO.Rys_napisy(Y-2,X,"N ",green);
TabNr(Lpobranych+1):=Kasa*100+Lodczytanych;
Numerek:=TabNr(Lpobranych+1);
Lpobranych:=Lpobranych+1;
Lodczytanych:=(Lodczytanych+1)mod 100;
delay(duration(0.1));
TLO.Rys_napisy(Y-2,X," ",white);
TLO.Rys_napisy(Y,X+2," ",white);
VB(Nr); -----SEKCJA KRYTYCZNA
return(Numerek);
end PNumerek;
procedure ONumerek(Y: integer ; X: integer ; pozy: in integer ; pozx: in integer ; Lp: in integer) is
begin
PB(Nr); -----SEKCJA KRYTYCZNA
TLO.Rys_napisy(pozy+1,pozx,"Nr: ",red);
temp:=1;
while (integer(TabNr(temp)/100)) /= Lp loop
temp:=temp+1;
end loop;
TLO.Rys_numer(pozy+1,pozx+4,TabNr(temp));
delay(duration(0.2));
for i in temp..Lpobranych loop
TabNr(i):=TabNr(i+1);
end loop;
Lpobranych:=Lpobranych - 1;
VB(Nr); -----SEKCJA KRYTYCZNA
end ONumerek;
--PROCES KASY -------------------------------------------
---KASA PIERWSZA-----
procedure Kasa1(Lp:integer ; X:integer ; Y:integer ; Numer: integer) is
czas: integer;
begin
PB(Kas1); -----SEKCJA KRYTYCZNA
czas:=randomint(15);
ONumerek(14,52,Y,X,Lp);
delay(duration(1));
if Numer<24 then
TLO.Rys_napisy(robo_Y+Numer,robo_X," ",white);
TLO.Rys_napisy(robo_Y+Numer,robo_X+1," ",white);
for i in 1..10 loop
TLO.Rys_klient(robo_Y+Numer,robo_X-i,Numer);
delay(duration(0.05));
TLO.Rys_napisy(robo_Y+Numer,robo_X-i," ",white);
end loop;
end if;
TLO.Rys_napisy(Y,X," ZAJETA",green);
TLO.Rys_klient(Y,X+10,Numer);
delay(duration(czas));
TLO.Rys_napisy(Y,X," WOLNA ",white);
TLO.Rys_napisy(Y,X+10," ",white);
TLO.Rys_napisy(Y+1,X," ",white);
delay(duration(1));
VB(Kas1); -----SEKCJA KRYTYCZNA
end Kasa1;
---KASA DRUGA-----
procedure Kasa2(Lp:integer ; X:integer ; Y:integer ; Numer: integer) is
czas: integer;
begin
PB(Kas2); -----SEKCJA KRYTYCZNA
czas:=randomint(15);
ONumerek(14,52,Y,X,Lp);
delay(duration(1));
if Numer<24 then
TLO.Rys_napisy(robo_Y+Numer,robo_X," ",white);
TLO.Rys_napisy(robo_Y+Numer,robo_X+1," ",white);
for i in 1..10 loop
TLO.Rys_klient(robo_Y+Numer,robo_X-i,Numer);
delay(duration(0.05));
TLO.Rys_napisy(robo_Y+Numer,robo_X-i," ",white);
end loop;
end if;
TLO.Rys_napisy(Y,X," ZAJETA",green);
TLO.Rys_klient(Y,X+10,Numer);
delay(duration(czas));
TLO.Rys_napisy(Y,X," WOLNA ",white);
TLO.Rys_napisy(Y,X+10," ",white);
TLO.Rys_napisy(Y+1,X," ",white);
delay(duration(1));
VB(Kas2); -----SEKCJA KRYTYCZNA
end Kasa2;
---KASA TRZECIA-----
procedure Kasa3(Lp:integer ; X:integer ; Y:integer ; Numer: integer) is
czas: integer;
begin
PB(Kas3); -----SEKCJA KRYTYCZNA
czas:=randomint(15);
ONumerek(14,52,Y,X,Lp);
delay(duration(1));
if Numer<24 then
TLO.Rys_napisy(robo_Y+Numer,robo_X," ",white);
TLO.Rys_napisy(robo_Y+Numer,robo_X+1," ",white);
for i in 1..10 loop
TLO.Rys_klient(robo_Y+Numer,robo_X-i,Numer);
delay(duration(0.05));
TLO.Rys_napisy(robo_Y+Numer,robo_X-i," ",white);
end loop;
end if;
TLO.Rys_napisy(Y,X," ZAJETA",green);
TLO.Rys_klient(Y,X+10,Numer);
delay(duration(czas));
TLO.Rys_napisy(Y,X," WOLNA ",white);
TLO.Rys_napisy(Y,X+10," ",white);
TLO.Rys_napisy(Y+1,X," ",white);
delay(duration(1));
VB(Kas3); -----SEKCJA KRYTYCZNA
end Kasa3;
--PROCES WEJŚCIA KLIENTA NA DWORZEC----------------------------------------------------
---WEJŚCIE 1
procedure Wejscie1(Numer: integer) is
begin
PB(we1);
for i in 1..10 loop
TLO.Rys_klient(5,74-i,Numer);
delay(duration(0.05));
TLO.Rys_napisy(5,74-i," ",white);
end loop;
delay(duration(0.1));
VB(we1);
end Wejscie1;
---WYJŚCIE 1
procedure Wyjscie1(Numer: integer) is
begin
PB(we1);
for i in 1..10 loop
TLO.Rys_klient(5,64+i,Numer);
delay(duration(0.05));
TLO.Rys_napisy(5,64+i," ",white);
end loop;
delay(duration(1));
VB(we1);
end Wyjscie1;
---WEJŚCIE 2
procedure Wejscie2(Numer: integer) is
begin
PB(we2);
for i in 1..10 loop
TLO.Rys_klient(12,74-i,Numer);
delay(duration(0.05));
TLO.Rys_napisy(12,74-i," ",white);
end loop;
delay(duration(0.1));
VB(we2);
end Wejscie2;
---WYJŚCIE 2
procedure Wyjscie2(Numer: integer) is
begin
PB(we2);
for i in 1..10 loop
TLO.Rys_klient(12,64+i,Numer);
delay(duration(0.05));
TLO.Rys_napisy(12,64+i," ",white);
end loop;
delay(duration(1));
VB(we2);
end Wyjscie2;
---PROCES KLIENTA ----------------------------------------------------
task type Klient(Lp:integer);
task body Klient is
wybor: integer;
wejscie: integer;
czas: integer;
Numerek:integer;
begin
loop
czas:=randomint(20);
wybor:=randomint(3);
wejscie:=randomint(2);
delay(duration(czas));
if wejscie=1 then Wejscie1(Lp);
else Wejscie2(Lp);
end if;
Numerek:=PNumerek(14,52,Lp,wybor);
if Lp<24 then
TLO.Rys_klient(robo_Y+Lp,robo_X,Lp);
TLO.Rys_numer(robo_Y+Lp,robo_X+5,Numerek);
end if;
if wybor=1 then Kasa1(1,2,5,Lp);
else
if wybor=2 then Kasa2(2,2,9,Lp);
else
if wybor=3 then Kasa3(3,2,13,Lp);
end if;
end if;
end if;
if wejscie=1 then Wyjscie1(Lp);
else Wyjscie2(Lp);
end if;
end loop;
end Klient;
------------------------------------------------
a:integer;
type wsk_klient is access klient;
klienci: array(1..50) of wsk_klient;
begin
Put("Podaj liczbe procesow: "); Get(item=>a);
TLO.Rys_budynek;
for i in 1..a loop
klienci(i):= new Klient(i);
end loop;
end DworzecSem;
STEROWANIE PROGRAMEM
Sterowanie programem polega na wpisaniu na początku jego wykonywania ilości procesów które chcemy żeby się wykonywały. Ustawiony jest możliwy zakres procesów do wyboru: od 0 do 24 (z zaznaczeniem że przy wyborze „0” program nie będzie się wykonywał poprawnie z braku klientów).
SZATA GRAFICZNA I WYGLĄD EKRANU
|
|
|
|
WYSTEPUJĄCE W PROGRAMIE PROCESY/ ZADANIA
W programie występują następujące procesy:
Proces klienta - Proces ten odpowiada za funkcjonalność programu. Klient wchodzi, pobiera numerek, jeżeli kasa jest zajęta to czeka, jeżeli jest pusta to zostaje obsłużony i opuszcza system.
Proces kasy - Proces ten zapewnia nam odpowiednie poruszanie klienta w obszarze poczekalni i kas, oraz sygnalizuje czy kasa jest wolna czy zajęta.
Proces numerka - Odwołując się do tego procesu klient pobiera numerek do kasy, oraz następnie zostaje umieszczony w poczekalni.
Proces rysowania dworca - Proces zajmujący się rysowaniem obszaru dworca: położenia wejść, kas, i poczekalni.
Proces wejścia - Proces zapewniający, że klient wejdzie na teren dworca.
Proces wyjścia - Proce zapewniający, że klient wyjdzie z terenu dworca.
DIAGRAM STANÓW UML
Strona | 13