Transcript 06.Semafory
Jarosław Kuchta
Semafory
Operacje
podniesienie semafora
opuszczenie semafora
Operacje są niepodzielne
(atomowe), tzn. że żadna z
tych operacji nie może zostać
przerwana.
Rodzaje semaforów
ogólny
binarny
ograniczony
uogólniony
Semafor ogólny
(definicja klasyczna Dijkstry)
Zmienna całkowita S:
podniesienie – V(S): S = S + 1;
opuszczenie – P(S): while (S<=0); S = S – 1;
Nie spełnia warunku niepodzielności
Semafor ogólny
(definicja praktyczna BenAriego)
Zmienna całkowita S:
podniesienie – V(S):
if (są procesy wstrzymane podczas opuszczania S)
wznów jeden z nich;
else
S = S +1;
opuszczenie – P(S):
if (S>0)
S = S – 1;
else
wstrzymaj;
Spełnia warunek niepodzielności
Konstrukcja semafora
Opuszczenie
Podniesienie
Proces A
Proces B
P(S):
V(S):
S=0
S=S-1
ktoś czeka
S=S+1
Semafor binarny
(definicja klasyczna)
Zmienna logiczna S:
podniesienie – VB(S): S = 1;
opuszczenie – PB(S): while (S==1); S = 0;
Semafor binarny
(definicja praktyczna)
Zmienna logiczna S:
podniesienie – VB(S):
if (są procesy wstrzymane podczas opuszczania S)
wznów jeden z nich;
else
S = 1;
opuszczenie – PB(S):
if (S==1)
S = 0;
else
wstrzymaj;
Semafor binarny a ogólny
Semafor binarny NIE jest szczególnym przypadkiem
semafora ogólnego.
Semafor binarny nie pamięta liczby operacji
podniesienia.
Semafor binarny może zastąpić ogólny, gdy realizuje
wzajemne wykluczanie.
Podniesienie już podniesionego semafora binarnego
jest błędem.
Semafor dwustronnie
ograniczony
Zmienna całkowita S z zakresu (0..N):
podniesienie – V(S):
if (S==N)
wstrzymaj;
else if (są procesy wstrzymane podczas opuszczania S)
wznów jeden z nich;
else
S = S + 1;
opuszczenie – P(S):
if (S==0)
wstrzymaj;
else if (są procesy wstrzymane podczas opuszczania S)
wznów jeden z nich;
else
S = S – 1;
Semafor uogólniony
Operacje podniesienia i opuszczenia mają dodatkowy operand n
podniesienie – V(S, n):
if (są procesy wstrzymane podczas opuszczania S o m)
{
wznów jeden z nich;
S = S – m + n;
}
else
S = S + n;
opuszczenie – P(S, n):
if (S >= n)
S = S – n;
else
wstrzymaj;
Jednoczesne operacje
semaforowe
Koniunktywna
PAND (S1, S2):
if (S1 > 0 && S2 > 0)
{
S1 = S1 – 1;
S2 = S2 – 1;
}
else
wstrzymaj;
Alternatywna
POR (S1, S2):
if (S1 > 0 || S2 > 0)
{
S1 = S1 – 1;
S2 = S2 – 1;
}
else
wstrzymaj;
Przykłady
Producenci i konsumenci
Czytelnicy i pisarze
Pięciu filozofów
1 producent i 1 konsument
Semaphore Wolne = N;
Semaphore Pełne = 0;
Dane[] bufor = new Dane[N];
void Producent ()
{
Dane dane;
int i = 0;
while (true)
{
Produkuj (out dane);
P(Wolne);
bufor [i] = dane;
i = (i + 1) % N;
V(Pełne);
}
}
void Konsument ()
{
Dane dane;
int j = 0;
while (true)
{
P(Pełne);
dane = bufor [j];
j = (j + 1) % N;
V(Wolne);
Konsumuj (dane);
}
}
Wielu producentów i
konsumentów
Semaphore Wolne = N;
Semaphore Pełne = 0;
Dane[] bufor = new Dane[N];
int j = 0; int k = 0
BinarySemaphore i_S = 1;
BinarySemaphore j_S = 1;
void Producent ()
{
Dane dane;
while (true)
{
Produkuj (out dane);
P(Wolne);
PB(i_S);
bufor [i] = dane;
i = (i+1) % N;
VB(i_S);
V(Pełne);
}
}
void Konsument ()
{
Dane dane;
while (true)
{
P(Pełne);
PB(j_S);
dane = bufor [j];
j = (j+1) % N;
VB(j_S);
V(Wolne);
Konsumuj (dane);
}
}
Czytelnicy i pisarze
int M; // liczba czytelników
int P; // liczba pisarzy
Semaphore Wolne = N; // liczba miejsc w czytelni
BinarySemaphore W = 1; // wzajemne wykluczanie się pisarzy
void Czytelnik ()
{
while (true)
{
Własne_Sprawy();
P(Wolne);
Czytanie();
V(Wolne);
}
}
void Pisarz ()
{
while (true)
{
Własne_Sprawy();
PB(W);
// Pisarz stopniowo zajmuje miejsca
// w czytelni
for (int j=0; j<M; j++) P(Wolne);
Pisanie();
VB(W);
}
}
Pięciu filozofów
(z możliwością zagłodzenia)
BinarySemaphore[] Pałeczki = new BinarySemaphore[] {1, 1, 1, 1, 1};
void Filozof(int i)
{
while (true)
{
Myślenie();
PB(Pałeczki, i);
PB(Pałeczki, (i+1) % 5);
Jedzenie();
VB(Pałeczki, i);
VB(Pałeczki, (i+1) % 5);
}
}
Pięciu filozofów
(z lokajem)
BinarySemaphore[] Pałeczki = new BinarySemaphore[] {1, 1, 1, 1, 1};
Semaphore Lokaj = 4;
void Filozof(int i)
{
while (true)
{
Myślenie();
P(Lokaj);
PB(Pałeczki, i);
PB(Pałeczki, (i+1) % 5);
Jedzenie();
VB(Pałeczki, i);
VB(Pałeczki, (i+1) % 5);
V(Lokaj);
}
}