Ostvariti program koji simulira tijek rezervacije stolova u nekom restoranu. Program na početku treba stvoriti određeni broj dretvi koji se zadaje u naredbenom retku. Svaka dretva/proces nakon isteka jedne sekunde provjerava ima li slobodnih stolova te slučajno odabire jedan od njih. Nakon odabira dretva ulazi u kritični odsječak te ponovo provjerava je li odabrani stol slobodan. Ako jest, označava stol zauzetim i izlazi iz kritičnog odsječka. U oba slučaja, nakon obavljene operacije ispisuje trenutno stanje svih stolova te podatke o obavljenoj rezervaciji. Prilikom ispisa za svaki stol mora biti vidljivo je li slobodan ili broj dretve/procesa koja je taj stol rezervirala. Broj stolova se također zadaje u naredbenom retku. Svaka dretva ponavlja isti postupak sve dok više nema slobodnih stolova. Program završava kada sve dretve završe.
Primjer ispisa: (3 dretve, 5 stolova)
Dretva 1: odabirem stol 2 Dretva 2: odabirem stol 2 Dretva 3: odabirem stol 5 Dretva 2: rezerviram stol 2, stanje: -2--- Dretva 1: neuspjela rezervacija stola 2, stanje: -2--- Dretva 3: rezerviram stol 5, stanje: -2--3 itd.Zaštitu kritičnog odsječka postupka rezervacije stola ostvariti koristeći Lamportov algoritam međusobnog isključivanja.
ULAZ[0..BR_DRETVI-1], BROJ[0..BR_DRETVI-1]
sve početno postavljeno u nulu
uđi_u_kritični_odsječak(I) ULAZ[I] = 1 BROJ[I] = max ( BROJ[0], ..., BROJ[BR_DRETVI-1] ) + 1 ULAZ[I] = 0 za J = 0 do BR_DRETVI-1 čini dok je ULAZ[J] <> 0 čini ništa dok je BROJ[J] <> 0 && (BROJ[J] < BROJ[I] || (BROJ[J] == BROJ[I] && J < I)) čini ništa izađi_iz_kritičnog_odsječka(I) BROJ[I] = 0
Veći dio rješenja je ponuđen kroz datoteke: lab2.py i lamport.py (i jednu i drugu je potrebno nadopuniti!)
#!/usr/bin/python # -*- coding: UTF-8 -*- import time, threading, signal, sys, random from lamport import KO_init, Udji_u_KO, Izadji_iz_KO kraj = False # na signal ova se varijabla mijenja # broj dretvi i stolova se zadaje preko komandne linije BR_DRETVI = 7 BR_STOLOVA = 5 stol = [] slobodno = BR_STOLOVA # broj slobodnih stolova def odaberi_slobodni_stol(): ''' Funkcija vraća indeks nasumično odabranog slobodnog stola ili -1 ako nema slobodnog stola. Ovo se može napraviti na razne načine. Jedan je opisan u nastavku. ''' # dok je slobodno > 0 radi # x = slučajan broj od 0 do slobodno-1 # y = 0 # za i = 0 do BR_STOLOVA-1 radi # ako je stol[i] == 0 tada # ako je x == y tada # vrati i # inače # y = y + 1 return -1 # nema slobodnih stolova def ispisi_stanje (): stanje = "".join ( str(x) if x > 0 else "-" for x in stol ) print ( "Stolovi: " + stanje ) def posao_dretve (id): ''' Početna funkcija za nove dretve ''' global slobodno while not kraj: # dok signal za kraj nije došao i = odaberi_slobodni_stol () if i == -1: break print ( "Dretva " + str(id) + ": odabirem stol " + str(i) ) time.sleep(1.0) Udji_u_KO (id-1) # id ide od 1-N, a polja od 0 do N-1 if stol[i] == 0: stol[i] = id slobodno = slobodno - 1 print ( "Dretva " + str(id) + ": rezerviram stol " + str(i) ) else: print ( "Dretva " + str(id) + ": neuspjela rezervacija stola " + str(i) ) ispisi_stanje () Izadji_iz_KO (id-1) time.sleep(1.0) def signal_kraj ( sig_num, frame ): ''' Na signal SIGINT (Ctrl+C) program završava ''' print ( "\nPrimljen signal za završetak ... ") global kraj kraj = True def main(): signal.signal ( signal.SIGINT, signal_kraj ) global BR_DRETVI, BR_STOLOVA, slobodno if len(sys.argv) == 3: BR_DRETVI = int(sys.argv[1]) BR_STOLOVA = int(sys.argv[2]) slobodno = BR_STOLOVA KO_init (BR_DRETVI) stol.extend ( [0] * BR_STOLOVA ) # u početku su svi stolovi slobodni ispisi_stanje () dretva = [None] * BR_DRETVI for i in range(BR_DRETVI): dretva[i] = threading.Thread ( target = posao_dretve, args = (i+1,) ) dretva[i].start() for i in range(BR_DRETVI): while dretva[i].is_alive(): dretva[i].join (timeout=1) if not kraj: print ( "Svi stolovi zauzeti" ) if __name__ == "__main__": main()
BR_DRETVI = 0 broj = [] ulaz = [] def KO_init (N): global BR_DRETVI BR_DRETVI = N broj.extend ( [0] * N ) ulaz.extend ( [0] * N ) def Udji_u_KO (I): # ostvariti prema algoritmu # može se koristiti funkcija max: broj[I] = max(broj) + 1 pass def Izadji_iz_KO (I): broj[I] = 0 # prema algoritmu
python lab2.py X Y
gdje je X
broj dretvi (npr. 7), a Y
broj stolova (npr. 5).Ako se pokreće iz nekog okruženja, npr. IDLE-a, onda je broj stolova i broj dretvi kodiran u kodu (tamo se može promijeniti).