W systemie operacyjnym współbieżnym procesy, które są w trakcie wykonania, mogą współpracować ze sobą lub działać niezależnie.

Proces niezależny (ang. independent) to taki, który nie może oddziaływać na inne procesy wykonywane w systemie, a i inne procesy nie mogą oddziaływać na niego. Procesy są więc niezależne tylko i tylko wtedy, gdy nie dzielą żadnych danych z żadnymi procesami.

Proces współpracujący (ang. cooperating) to taki, który może wpływać na inne procesy lub inne procesy mogą oddziaływać na niego. Analogicznie, proces współpracujący to proces dzielący dane z innymi procesami.

Dzięki wprowadzeniu środowiska umożliwiającego współpracę pomiędzy procesami możliwe staje się [1]:

Zagadnienie producenta-konsumenta (ang. producer-consumer problem) stanowi model współpracy procesów.

Zakładamy, że proces producent wytwarza dane, które konsumuje proces konsumenta. Aby było to możliwe musi istnieć bufor (wyobraźmy sobie go jako tablicę) jednostek, który będzie zapełniany przez producenta i opróżniany przez konsumenta. W takim układzie, gdy producent produkuje jednostkę, konsument może wyciągnąć z bufora inną. Ważne jest jednak, aby procesy producenta i konsumenta podlegały synchronizacji tak, by konsument nie "wyciągał" jednostek jeszcze niewyprodukowanych, a w przypadku pustego bufora poczekał na wyprodukowanie czegoś do "wyciągania".

[Produkcja i konsumpcja]

Rysunek 5.1. Producent, bufor oraz konsument

Problem producenta-konsumenta może być dwojakiego rodzaju [1]:


Poniższy algorytm przedstawia rozwiązanie problemu producenta-konsumenta z ograniczonym buforem, który używa pamięci dzielonej. W algorytmie tym procesy konsumenta i producenta korzystają z następujących wspólnych zmiennych:

    var n;
    type jednostka=...;
    var bufor: array [0..n-1] of jednostka;
           we, wy: 0..n-1;
// rozmiar bufora
// jednostka do konsumpcji
// bufor jako tablica cykliczna
// wskaźniki do wejścia i wyjścia bufora
Zmienna we wskazuje na następne wolne miejsce w buforze. Gdy bufor jest pusty wskaźniki we i wy pokrywają się. Gdy bufor jest pełny we+1 mod n = wy (mod oznacza resztę z dzielenia).

Poniżej przedstawione są kody procesów producenta i konsumenta. Wyjaśnijmy Instrukcja nic jest instrukcją pustą tzn. jej wykonanie nie daje żadnego efektu. Jednostki nowo produkowane znajdują się w zmiennej lokalnej nowyprodukt, zaś jednostki do skonsumowania są przechowywane w zmiennej nowakonsumpcja.

A oto i proces producenta:
repeat
    ...
    // produkuj jednostkę w nowyprodukt
    ...
    while we+1 mod n=wy do nic;
    bufor[we]:=nowyprodukt;
we:=we+1 mod n;
until false
Proces konsumenta ma natomiast taką postać:
repeat
    while we=wy do nic;
    nowakonsumpcja:=bufor[wy];
    wy:=wy+1 mod n;
    ...
    // konsumuj jednostkę z nowakonsumpcja
    ...
until false
Podany algorytm umożliwia używać co najwyżej n-1 jednostek bufora w tym samym momencie.


NASTĘPNA