###### tags: `prir` `studia` # Problem producenta i konsumenta ## Zarys problemu Zadania dzielimy na dwie grupy ### Producenci produkują dane do przetworzenia ### Konsumenci przetwarzają wyprodukowane dane > Najprostszy wariant opiera się na jednym Producencie oraz jednym Konsumencie. Gdy tylko Producent przygotuje dane, wysyła je do Konsumenta, a ten je przetwarza. ## Rozwiązanie synchroniczne **Konsument nie jest gotowy na przyjęcie danych** = Producent czeka **Producent nie przygotował danych** = Konsument czeka ## Rozwiązanie asynchroniczne Zastosujemy **bufor**, gdzie Producent wstawia dane, a Konsument odczytuje. ### Rodzaje bufora - ograniczony - nieograniczony ## Rozwiązanie z użyciem bufora nieograniczonego i semafora ogólnego ``` T bufor[infinity] Semaphore sa_dane = (0, {}) -> PRODUCENT: int prodIndex = 0; loop infinity { T dane = Produkuj() bufor[prodIndex] = dane ++prodIndex; signal(sa_dane); } -> KONSUMENT: int consIndex = 0; loop infinity { wait(sa_dane) T dane = bufor[consIndex] ++consIndex Konsumuj(dane) } ``` ## Rozwiązanie z użyciem bufora ograniczonego ``` T bufor[0..n-1] Semaphore sa_dane = (0, {}) Semaphore jest_miejsce = (n, {}) -> PRODUCENT: int prodIndex = 0; loop infinity { T dane = Produkuj(); wait(jest_miejsce) bufor[prodIndex] = dane prodIndex = (prodIndex+1)%n signal(sa_dane) } -> KONSUMENT: int consIndex = 0; loop infinity { wait(sa_dane) T dane = bufor[consIndex] consIndex = (consIndex+1)%n signal(jest_miejsce) Konsumuj(dane) } ``` ### Rozwiązanie z użyciem bufora ograniczonego oraz monitora ``` monitor ProducentKonsument { T bufor[0..n-1]; int prodIndex=0, consIndex=0, licznik=0; Condition sa_dane, jest_miejsce; void wstaw(T dane) { if (licznik==n) wait(jest_miejsce) bufor[prodIndex] = dane; prodIndex = (prodIndex+1)%n ++licznik signal(sa_dane) } T pobierz() { if (licznik==0) wait(sa_dane) T dane = bufor[consIndex]; consIndex = (consIndex+1)%n --licznik signal(jest_miejsce) return dane } } // tworzymy monitor ProducentKonsument m -> PRODUCENT loop infinity { T dane = Produkuj(); m.wstaw(dane) } -> KONSUMENT loop infinity { T dane = m.pobierz() Konsumuj(dane) } ``` ### Rozwiązanie z użyciem przestrzeni krotek i nieograniczonego bufora ``` -> PRODUCENT T dane int licznik=0 loop forever { dane = produkuj() postnote('b', licznik, dane) licznik++ } -> KONSUMENT T dane int licznik=0 loop forever { removenote('b', licznik=, dane) konsumuj(dane) licznik++ } ``` ### Rozwiązanie z użyciem przestrzeni krotek i ograniczonego bufora ``` T bufor[0..n-1] Semaphore jest_miejsce = (n, {}) -> PRODUCENT T dane int licznik=0 loop forever { dane = produkuj wait(jest_miejsce) postnote('b', licznik, dane) licznik = (licznik+1)%n } -> KONSUMENT T dane int licznik=0 loop forever { removenote('b', licznik=, dane) licznik = (licznik+1)%n konsumuj(dane) } ```