Koordynacja procesów


Sekcje krytyczne

- wzajemne wyłączanie SK

- ograniczone (skończone) czekanie na wejście do SK





repeat

while x<>0 do nic (sekcja wejściowa)

<SK> (SK)

x:=1 (sekcja wyjściowa)

<reszta kodu procesu>

until false (narzucone naprzemienne (czyli nie spełniające warunku postępu) wykonanie SK dla 2(może być więcej) procesów)

var flaga: array[o..1] of Boolean

numer: 0..1

repeat

flaga[i]:=TRUE (chcę wejść)

numer:=j (założenie, że drugi chce wejść)

while (flaga[j] AND numer:=j)do nic

<SK>

flaga[i]:=FALSE

<reszta kodu procesu>

until false (bez zmiennej numer możliwe byłoby ustawienie obu flag przez procesy w dwóch kolejnych instrukcjach procesora (po pechowym przełączeniu kontekstu) i wieczne ich zapętlenie...)


4.2 Semafory

- czekaj(s): while s <= 0 do nic; s := s-1;

- sygnalizuj(s): s := s+1;

- na pojedynczym CPU – zablokowanie przerwań na czas operacji

- w systemie wieloprocesorowym instrukcja procesora TEST&SET

s:=1

repeat

czekaj(s)

<SK>

sygnalizuj(s)

<reszta kodu procesu>

until false

s:=0

1proces: op1; 2proces: czekaj(s);

sygnalizuj(s); op2;




Blokady.


np.:

Semafory A i B mają wartość 1:

P0: wait(A); wait(B)

P1: wait(B); wait(A)


  1. Wzajemne wyłączanie (co najmniej 1 zasób musi być niepodzielny)

  2. Przetrzymywanie i oczekiwanie (proces przetrzymujący co najmniej jeden zasób czeka na przydział dodatkowych zasobów będących w posiadaniu innych procesów).

  3. Nie ma wywłaszczania z zasobów.

  4. Cykliczne czekanie (istnieje zbiór czekających procesów {P0, P1, Pn }, takich że P 0 czeka na zasób przetrzymywany przez P1 , P1 czeka na zasób przetrzymywany przez P2 , ..., P n czeka na zasób przetrzymywany przez P0 .

(4 implikuje 2, więc podane warunki nie są niezależne)




Zapobieganie i unikanie blokad.


powyższe metody zawsze ograniczają przepustowość systemu...





Założenia:

n – liczba procesów

m – liczba typów zasobów

int Dostępne[m] – liczba zasobów określonego typu (np. Dostępne[3]=5 to 5 zasobów typu 3)

int Maks[n][m] – maksymalne żądania procesów

int Przydzielone[n][m] – przydzielone zasoby

int Potrzebne[n][m] – potrzebne zasoby (z tym, że Potrzebne[i][j]=Maks[i][j]-Przydzielone[i][j])

int Zamówienia[n][m] – aktualne zamówienia procesu.

Algorytm:

  1. Jeśli Zamówienia[i] <= Potrzebne[i] to wykonaj krok 2. Wpp błąd – proces przekroczył deklarowane zapotrzebowanie.

  2. Jeśli Zamówienia[i] <= Dostępne wykonaj krok 3. Wpp proces i musi czekać.

  3. System próbuje przydzielić żądane zasoby procesowi i zmieniając stan systemu w następujący sposób:
    Dostępne = Dostępne – Zamówienia[i]

Przydzielone[i] = Przydzielone[i] + Zamówienia[i]

Potrzebne[i] = Potrzebne[i] – Zamówienia[i]

Jeśli stan po zmianie jest bezpieczny, transakcja dochodzi do skutku. Jeśli nie – proces i musi czekać...


Algorytm bezpieczeństwa:

  1. int Praca[m]; int Koniec[n]

  2. Praca = Dostępne; Koniec[i] = FALSE dla wszystkich i

  3. Znajdujemy i takie że Koniec[i]=FALSE oraz Potrzebne[i] <= Praca; Jeśli nie ma takiego i do kroku 5.

  4. Praca = Praca + Przydzielone[i]; Koniec[i] = TRUE; przejdź do kroku 2.

  5. Jeśli Koniec[i] = TRUE dla wszystkich i, to system jest w stanie bezpiecznym...

Koszt stwierdzenia czy system jest bezp. = m x n2


Wykrywanie i wychodzenie z blokady.




całej pętli (znaczny koszt, utrata częściowych wyników)

kolejno (wywołanie szukania cykli po każdym usunięciu)

- różne kryteria wyboru ofiary (priorytet, typ, posiadane zasoby...)



- zasoby wewnętrzne (bloki kontr. itp...) uporządkowanie zasobów

- pamięć głowna

- urządzenie i pliki unikanie blokad