Pobierz prezentację
Pobieranie prezentacji. Proszę czekać
1
Jarosław Kuchta Monitory
2
Co to jest monitor Monitor to zebrane w jednej konstrukcji programowej zmienne i operacje na tych zmiennych. Część tych operacji jest udostępnianych na zewnątrz monitora. Tylko udostępnione operacje umożliwiają działanie na zmiennych. Wykonanie operacji monitora jest sekcją krytyczną wykonującego ją procesu. Wewnątrz monitorowanej operacji istnieje możliwość wstrzymywania i wznawiania procesów.
3
Szczegóły zmienna c typu contition operacje:
umożliwia wstrzymywanie / wznawianie procesów posiada własną kolejkę procesów operacje: wait(c) – powoduje wstrzymanie procesu wykonującego tę operację; proces jest wstawiany na koniec kolejki właściwej dla zmiennej c; monitor jest zwalniany signal(c) – powoduje wznowienie wstrzymanego procesu; wznawiany jest pierwszy proces z kolejki właściwej dla zmiennej c; proces ten czeka, aż proces wywołujący tę operację zwolni monitor empty(c) – funkcja sprawdzająca, czy kolejka właściwa dla zmiennej c nie jest pusta
4
Przechodzenie procesów przez monitor
Monitor M kolejka wejściowa kolejka procesów oczekujących na C void P(float x) { … wait (C); signal (C); } M.P(1.0) kolejka procesów wstrzymanych po signal
5
Przykłady Wzajemne wykluczanie Producenci i konsumenci
Czytelnicy i pisarze Pięciu filozofów
6
Wzajemne wykluczanie static class Wykluczanie: Monitor {
public static void Dostęp() Enter (this); // Działanie na zasobach Exit (this); } class ProcesGłówny { void Działaj() // własne sprawy Wykluczanie.Działaj(); }
7
Producenci i konsumenci
Monitor Bufor; Object Producenci = new Object(); Object Konsumenci = new Object(); const int N=10; Dane[] bufor = new Dane[N]; int n=0; int i = 0; int j = 0; void Produkuj (Dane element) { if (n == N) Bufor.Wait (Producenci); n = n + 1; bufor[ i] = element; i = (i+1) % N; Bufor.Signal (Konsumenci); } void Konsumuj (out Dane element) { if (n == 0) Bufor.Wait (Konsumenci); n = n – 1; element = bufor [j]; j = (j+1) % N; Bufor.Signal (Producenci); }
8
Czytelnicy i pisarze (z możliwością zagłodzenia pisarza)
class Czytelnia: Monitor { Object Czytelnicy = new Object(); Object Pisarze = new Object(); int ile_czyta = 0; int ile_pisze = 0; void Początek_Pisania() { if (ile_czyta + ile_pisze > 0) Wait (Pisarze); ile_pisze = 1; } void Początek_Czytania() { if (ile_pisze > 0) Wait (Czytelnicy); ile_czyta++; } void Koniec_Pisania() { ile_pisze = 0; if (!Empty(Pisarze) Signal (Pisarze) else do Signal (Czytelnicy) while (!Empty(Czytelnicy)) } void Koniec_Czytania() { ile_czyta--; if (ile_czyta == 0) Signal (Pisarze); }
9
Czytelnicy i pisarze (rozwiązanie poprawne)
class Czytelnia: Monitor { Object Czytelnicy = new Object(); Object Pisarze = new Object(); int ile_czyta = 0; int ile_pisze = 0; void Początek_Pisania() { if (ile_czyta + ile_pisze > 0) Wait (Pisarze); ile_pisze = 1; } void Początek_Czytania() { if (!Empty(Czytelnicy) || ile_pisze > 0) Wait (Czytelnicy); ile_czyta++; } void Koniec_Pisania() { ile_pisze = 0; if (!Empty(Pisarze) Signal (Pisarze) else do Signal (Czytelnicy) while (!Empty(Czytelnicy)) } void Koniec_Czytania() { ile_czyta--; if (ile_czyta == 0) Signal (Pisarze); }
10
Pięciu filozofów (przymiarka pierwsza)
class Pałeczki: Monitor { int [] wolne = new int[] { 2, 2, 2, 2, 2}; object [] Filozof = new object[5]; void Biorę(int i) { while (wolne [i] < 2) Wait (Filozof [i]); wolne [(i–1 ) % 5] = wolne [(i–1) % 5] - 1; wolne [(i+1) % 5] = wolne [(i+1) % 5] - 1; } void Odkładam(int i) { wolne [(i–1) % 5] = wolne [(i–1) % 5] + 1; wolne [(i+1) % 5] = wolne [(i+1) % 5] + 1; Signal (Filozof[(i–1) % 5]); Signal (Filozof[(i+1) % 5]); }
11
Pięciu filozofów (przymiarka druga)
class Pałeczki: Monitor { int [] wolne = new int[] { 2, 2, 2, 2, 2}; object [] Filozof = new object[5]; void Biorę(int i) { while (wolne [i] < 2) Wait (Filozof [i]); wolne [(i–1 ) % 5] = wolne [(i–1) % 5] - 1; wolne [(i+1) % 5] = wolne [(i+1) % 5] - 1; } void Odkładam(int i) { wolne [(i–1) % 5] = wolne [(i–1) % 5] - 1; wolne [(i+1) % 5] = wolne [(i+1) % 5] - 1; if (wolne[(i-1) % 5] == 2) Signal (Filozof[(i–1) % 5]); if (wolne[(i+1) % 5] == 2) Signal (Filozof[(i+1) % 5]); }
12
Pięciu filozofów (rozwiązanie poprawne)
class Pałeczki: Monitor { bool [] zajęta = new bool[5]; object [] Pałeczka = new object[5]; object Lokaj = new object(); int ile_je = 0; void Biorę(int i) { if (ile_je == 4) Wait (Lokaj); ile_je ++; if (zajęta [i]) Wait (Pałeczka [i]); zajęta[ i] = true; if (zajęta[(i+1) % 5]) Wait (Pałeczka [(i+1) % 5]); zajęta[(i+1) % 5] = true; } void Odkładam(int i) { zajęta [i] = false; Signal (Pałeczka[i]); zajęta [(i+1) % 5] = false; Signal (Pałeczka[(i+1) % 5]); ile_je --; Signal (Lokaj); }
13
Implementacje Monitora
Zmienne warunkowe z blokowaniem Zmienne warunkowe bez blokowania Monitory z niejawnym warunkiem
14
Zmienne warunkowe z blokowaniem (monitor Hoara)
wątek powiadamiający jest blokowany do czasu, aż powiadomiony wątek oczekujący nie opuści monitora lub nie zatrzyma się w ponownym oczekiwaniu na warunek. dwie główne kolejki wątków: e - kolejka wejściowa s - kolejka wątków powiadamiających każda zmienna warunkowa c posiada własną kolejkę c.q wątków oczekujących na spełnienie warunku. enter e s a.q wait(a) signal b.q wait(b) exit
15
Zmienne warunkowe bez blokowania (monitor Massy)
operacja signal nie powoduje opuszczenia monitora wątek oczekujący jest przenoszony do kolejki e, aby zaczekać, aż wątek powiadamiający zakończy swoje zadanie kolejka s jest niepotrzebna operacja signal nazywa się teraz notify enter notified e notified wait(b) b.q a.q wait(a) exit
16
Monitory z niejawnym warunkiem
W języku Java każdy obiekt może stać się monitorem metody wykluczane są oznaczone słowem kluczowym synchronized. monitor ma kolejkę wejściową i pojedynczą kolejkę wszystkie operacje dotyczą tej jednej kolejki (najwyżej jeden warunek) enter e notified wait q exit
17
Klasa Monitor w C# (1) public static class Monitor
public static void Enter (Object obj) – wejście do monitora public static bool TryEnter (Object obj) public static bool TryEnter (Object obj, int millisecondsTimeout) public static bool TryEnter (Object obj, TimeSpan timeout) public static void Exit (Object obj) – wyjście z monitora
18
Klasa Monitor w C# (2) public static bool Wait (Object obj) – oczekiwanie public static bool Wait (Object obj, int millisecondsTimeout) public static bool Wait(Object obj, TimeSpan timeout) public static bool Wait (Object obj, int millisecondsTimeout, bool exitContext) public static bool Wait( Object obj, TimeSpan timeout, bool exitContext ) public static void Pulse (Object obj) – sygnalizacja public static void PulseAll (Object obj) – sygnalizacja do wszystkich
Podobne prezentacje
© 2024 SlidePlayer.pl Inc.
All rights reserved.