Programowanie współbieżne i rozproszone/PWR Wykład 8

Z Studia Informatyczne
Przejdź do nawigacjiPrzejdź do wyszukiwania

Model scentralizowany

Cechy

Przechodzimy teraz do mechanizmów synchronizacji w systemach ze wspólną pamięcią. Model ten różni się od dotychczasowych przede wszystkim tym, że można stosować zmienne współdzielone, czyli dostępne dla wielu procesów, i za ich pomocą wymieniać informacje.

Korzystanie ze zmiennych współdzielonych wymaga jednak dużej ostrożności, jak widzieliśmy to podczas pierwszego wykładu. Niekontrolowane niczym modyfikowanie takich zmiennych w wielu procesach jednocześnie może dawać niedające się przewidzieć efekty. Z tego powodu większość z omawianych w dalszym ciągu mechanizmów gwarantuje atomowość lub niepodzielność pewnych operacji.

Mechanizmy

W dalszej części wykładu omówimy szczegółowo dwie metody synchronizacji procesów w środowisku scentralizowanym: semafory i monitory. Wspomnimy także o mechanizmie zamków (muteksów). Zanim jednak to nastąpi na przykładzie wzajemnego wykluczania wspomnijmy o dwóch innych metodach synchronizacji.

Pierwsza z tym metod jest stosowana wtedy, gdy nie dysponujemy żadnym wsparciem ani ze strony sprzętu ani oprogramowania. Korzystając jedynie z wysokopoziomowych instrukcji języka programowania można zapewnić wzajemne wykluczanie w dostępie do sekcji krytycznej za pomocą m.in. algorytmu Petersona. Jego dokładne omówienie znalazło się w materiałach dotyczących pierwszych ćwiczeń. Przypomijmy jego wady: statycznie znana liczba procesów, koszt, a przede wszystkim aktywne oczekiwanie.

Czasem możemy liczyć na wsparcie sprzętowe. Może to być na przykład specjalny rozkaz maszynowy realizujący niepodzielny zapis i odczyt. Rozpatrzmy dla przykładu rozkaz Test_and_Set, który odczytuje pewien bit G i ustawia go na jeden. Działanie takiego rozkazu można by zapisać w wysokopoziomowym języku następująco:

procedure Test_and_Set (var L: 0..1);
{ Ta procedura jest atomowa! }
begin
  L := G;
  G := 1;
end   

Problem wzajemnego wykluczania można wówczas rozwiązać następująco:

var
  wolny: 0..1 := 0;
process P;
var
  i: 0..1;
begin
  repeat
    własne_sprawy;
    repeat
      Test_and_Set (i);
    until i = 0;
    sekcja_krytyczna;
    wolny := 0;
  until false
end; 

To rozwiązanie także nie jest pozbawione wad. Pierwszą z nich jest oczywiście aktywne oczekiwanie, drugą możliwość zagłodzenia procesu.

Semafory jako abstrakcyjny typ danych

Klasyczna definicja semafora

Definicja uproszczona

Semafor binarny

Przykład. Produceni i konsumenci

Symulacja semafora ogólnego binarnymi

Dziedziczenie sekcji krytycznej

Semafory w systemie Unix

Zestawy semaforów

Jednoczesne operacje semaforowe

Przykład

Czytelnicy i pisarze. Wersja 1

Czytelnicy i pisarze. Wersja 2

Inne rodzaje semaforów

Semafory dwustronnie ograniczone

Semafory uogólnione

Semafory Agerwali