###### 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)
}
```