Implementujte ADT Lightswitch. ADT Lightswitch nech poskytuje 2 metódy: lock
a unlock
podľa nasledovnej špecifikácie:
lock(semaphore)
unlock(semaphore)
Interný stav ADT Lightswitch je daný počítadlom counter
a mutexom mutex
, ktorý chráni integritu počítadla.
Správanie ADT Lightswitch:
lock
, a toto vlákno je prvým, ktoré sa pokúša „dostať do miestnosti“, nech vyvolá nad semaforom, ktorý je argumentom funkcie lock
, operáciu wait()
. unlock
, a toto vlákno je posledným, ktoré sa pokúša „dostať z miestnosti“, nech vyvolá nad semaforom, ktorý je argumentom funkcie unlock
, operáciu signal()
. Na jednoduchom príklade overte funkčnosť svojej implementácie. Tento ADT správne využite v niektorej z nasledovných úloh.
Implementujte riešenie problému Konzument-Producent. Experimentujte s rôznymi nastaveniami systému:
Skúste experimentálne zistiť, aké parametre sú optimálne pre váš systém. Kritériom optimality nech sú:
V prípade experimentov priemerujte hodnoty 10 opakovaní experimentu pri rovnakých nastaveniach systému; grafy vykresľujte aspoň pre 100 rôznych nastavení modelovaného systému.
Podobne ako v prípade problematiky Producentov-Konzumentov, aj tu experimentujte s rôznymi nastaveniami systému. Implementujte dve verzie riešenia tohto problému:
Experimentujte s nasledovnými parametrami systému, a hľadajte medzi nimi závislosti:
Podobne ako pri probléme producent-konzument, aj pri týchto experimentoch opakujte merania aspoň 10x pre rovnaké nastavenie systému, a výsledky priemerujte; grafy vykresľujte aspoň pre 100 rôznych nastavení modelovaného systému.
Pri písaní kódu dbajte na prehľadnosť, samočitateľnosť, modularitu a znovupoužiteľnosť kódu. Dodržiavajte štandard PEP8. Vhodne využívajte možnosť komentovania kódu, viď štandard PEP257.
Do experimentov vhodným spôsobom vnášajte náhodnosť. Napr. kód zapisovateľa by mohol mať nasledovnú štruktúru:
1 2 3 4 5 6 7 8 9 10 11 12 13 |
from time import sleep from random import randint def writer_thread(thread_id, shared): while True: # pred kazdym pokusom o zapis pocka v intervale <0.0; 1> sekundy sleep(randint(0, 10)/10) shared.roomEmpty.wait() # simulujeme dlzku zapisu v intervale <0.3; 0.7> sekundy sleep(0.3 + randint(0, 4)/10) shared.room_empty.signal() |
Pre zopakovanie uvádzame aj kód vytvorenia vlákien.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 |
from fei.ppds import Thread, Semaphore, print class Shared(): def __init__(self): self.room_empty = Semaphore(1) """ Vytvorime vlakna, ktore chceme synchronizovat. Nezabudnime vytvorit aj zdielane synchronizacne objekty, a dat ich ako argumenty kazdemu vlaknu, ktore chceme pomocou nich synchronizovat. """ shared = Shared() threads = [] for i in range(10): t = Thread(writer_thread, f"Writer {i}", shared) threads.append(t) for t in threads: t.join() |
Vyberte si jednu z úloh P-K alebo R-W.