Problem pospane frizerke
(Izvorno Sleeping barber problem)

Zadatak

U nekom frizerskom salonu radi jedna frizerka. Salon ima odvojenu čekaonicu s N=3 mjesta gdje čekaju klijenti. Frizerka ima samo jedan stolac u koji može primiti klijenta i raditi na njegovoj frizuri.
Frizerka ujutro otvara vrata salona i do kraja radnog vremena obavlja sljedeću cikličku aktivnost: sjeda u stolac i spava dok ju ne probudi dolazak klijenta ili joj sat zazvoni kada je kraj radnog vremena. Ako je došao klijent uzima ga i radi na njegovoj frizuri. Potom, ako ima još klijenata uzima ih redom, jednog po jednog. Ako je čekaonica prazna, opet sjeda u stolac i spava. Kada u čekaonici ima klijenata frizerka ne smije spavati.
Novi klijent prvo ude u čekaonicu. Ako nema praznih mjesta, tj. u čekaonici već čeka N klijenata, klijent odlazi bez obavljena posla. Ako ima praznih stolaca, sjeda i signalizira svoj dolazak frizerki. Kada ga frizerka pozove dolazi k njoj na frizuru. Potom odlazi iz salona.

Simulirati prikazani sustav dretvom frizerka te dretvama klijent. Dretvu frizerka te dretve klijent stvara početna (glavna) dretva. Najprije stvori jednu dretvu frizerke, potom po jednu dretvu klijenta svake dvije sekunde. Nakon što je stvoreno 20 dretvi klijenata, glavna dretva označava kraj radnog vremena, ali nakon toga stvara još 3 dretve (svaku nakon 2 sekunde). Frizerka mora odraditi sve klijente iz salona prije nego zatvori salon. Trajanje rada na jednom klijenut simulirati s odgodom od 5 sekundi. Za sinkronizaciju koristiti semafore i dodatne varijable.

Prijedlog strukture rješenja (frizerka.py):

def frizerka ():
    # uđi u kritični odsječak
    otvoren = True # postavi oznaku OTVORENO
    ispisi_stanje("frizerka: otvaram salon")
    # izađi iz kritičnog odsječka
    while not prekini: # nije zahtjevan prekid izvođenja
        # uđi u kritični odsječak
        if len(red) > 0: # ima klijenata
            # pozovi idućeg klijenta
            # izađi iz kritičnog odsječka
            time.sleep(5)
        elif otvoren:
            stolac = 0
            ispisi_stanje("frizerka: spavam")
            # izađi iz kritičnog odsječka
            # spavaj - čekaj da te probude
        else:
            stolac = 0
            ispisi_stanje("frizerka: zavrsavam s radom")
            # izađi iz kritičnog odsječka
            break

def klijent (id):
    # uđi u kritični odsječak
    if otvoren and len(red) < 3:
        red.append(id)
        ispisi_stanje("klijent " + str(id) + ": dosao")
        if stolac == 0:
            # probudi frizerku
            pass
        # izađi iz kritičnog odsječka
        # čekaj da te frizerka pozove
        if prekini: return
        # uđi u kritični odsječak
        stolac = id
        red.remove(id)
        ispisi_stanje("klijent " + str(id) + ": radi mi frizuru")
    elif not otvoren:
        ispisi_stanje("klijent " + str(id) + ": salon zatvoren")
    else:
        ispisi_stanje("klijent " + str(id) + ": nema mjesta")
    # izađi iz kritičnog odsječka

Primjer ispisa:

OTVORENO  stolac: 0 red: - - - [ frizerka: otvaram salon ]
OTVORENO  stolac: 0 red: - - - [ frizerka: spavam ]
OTVORENO  stolac: 0 red: 1 - - [ klijent 1: dosao ]
OTVORENO  stolac: 1 red: - - - [ klijent 1: radi mi frizuru ]
OTVORENO  stolac: 1 red: 2 - - [ klijent 2: dosao ]
OTVORENO  stolac: 1 red: 2 3 - [ klijent 3: dosao ]
OTVORENO  stolac: 2 red: 3 - - [ klijent 2: radi mi frizuru ]
OTVORENO  stolac: 2 red: 3 4 - [ klijent 4: dosao ]
OTVORENO  stolac: 2 red: 3 4 5 [ klijent 5: dosao ]
OTVORENO  stolac: 2 red: 3 4 5 [ klijent 6: nema mjesta ]
OTVORENO  stolac: 3 red: 4 5 - [ klijent 3: radi mi frizuru ]
OTVORENO  stolac: 3 red: 4 5 7 [ klijent 7: dosao ]
OTVORENO  stolac: 3 red: 4 5 7 [ klijent 8: nema mjesta ]
OTVORENO  stolac: 4 red: 5 7 - [ klijent 4: radi mi frizuru ]
OTVORENO  stolac: 4 red: 5 7 9 [ klijent 9: dosao ]
OTVORENO  stolac: 4 red: 5 7 9 [ klijent 10: nema mjesta ]
ZATVORENO stolac: 4 red: 5 7 9 [ main: zatavaram salon ]
ZATVORENO stolac: 4 red: 5 7 9 [ klijent 11: salon zatvoren ]
ZATVORENO stolac: 5 red: 7 9 - [ klijent 5: radi mi frizuru ]
ZATVORENO stolac: 5 red: 7 9 - [ klijent 12: salon zatvoren ]
ZATVORENO stolac: 5 red: 7 9 - [ klijent 13: salon zatvoren ]
ZATVORENO stolac: 7 red: 9 - - [ klijent 7: radi mi frizuru ]
ZATVORENO stolac: 9 red: - - - [ klijent 9: radi mi frizuru ]
ZATVORENO stolac: 0 red: - - - [ frizerka: zavrsavam s radom ]