Università degli Studi della Calabria
Corso di Laurea in Ingegneria Informatica
A.A. 2001/2002
Sistemi Operativi
Corsi A e B
Esercitazioni 1 e 2
Sincronizzazione dei Processi (1a parte)
n Introduzione
n Il problema della sezione critica
n Soluzioni hardware per la sincronizzazione
n Semafori
Sistemi Operativi
P.Trunfio – R.Ortale
1
Introduzione
n L’accesso concorrente a dati condivisi può
portare all’inconsistenza dei dati.
n Per garantire la consistenza dei dati sono
necessari meccanismi per assicurare
l’esecuzione ordinata dei processi cooperanti.
Sistemi Operativi
P.Trunfio – R.Ortale
Bounded-Buffer (1)
n Dati condivisi
class item {
...
}
…
int BUFFER_SIZE = 10;
item buffer[] = new item [BUFFER_SIZE];
int in = 0;
int out = 0;
int counter = 0;
…
Sistemi Operativi
P.Trunfio – R.Ortale
2
Bounded-Buffer (2)
n Processo produttore
item nextProduced;
while (true) {
nextProduced = new item (…);
while (counter == BUFFER_SIZE) ; /* do nothing */
buffer[in] = nextProduced;
in = (in + 1) % BUFFER_SIZE;
counter++;
}
Sistemi Operativi
P.Trunfio – R.Ortale
Bounded-Buffer (3)
n Processo consumatore
item nextConsumed;
while (true) {
while (counter == 0) ; /* do nothing */
nextConsumed = buffer[out];
out = (out + 1) % BUFFER_SIZE;
counter--;
}
Sistemi Operativi
P.Trunfio – R.Ortale
3
Bounded-Buffer (4)
n Le istruzioni:
counter++;
counter--;
devono essere eseguite atomicamente.
n Una operazione atomica è una operazione che si
completa nella sua interezza senza interruzioni.
Sistemi Operativi
P.Trunfio – R.Ortale
Bounded-Buffer (5)
n L’istruzione “counter++” può essere implementata in
linguaggio macchina come:
register1 = counter
register1 = register1 + 1
counter = register1
n L’istruzione “counter--” può essere implementata come:
register2 = counter
register2 = register2 – 1
counter = register2
Sistemi Operativi
P.Trunfio – R.Ortale
4
Bounded-Buffer (6)
n Nel caso in cui il produttore ed il consumatore
cercassero di aggiornare il buffer contemporaneamente,
le istruzioni in linguaggio assembly potrebbero risultare
interfogliate (interleaved).
n L’interleaving dipende da come i due processi
produttore e consumatore sono schedulati.
Sistemi Operativi
P.Trunfio – R.Ortale
Bounded-Buffer (7)
n Si assuma che counter sia inizialmente 5. Un possibile
interleaving delle istruzioni è:
producer: register1 = counter (register1 = 5)
producer: register1 = register1 + 1 (register1 = 6)
consumer: register2 = counter (register2 = 5)
consumer: register2 = register2 – 1 (register2 = 4)
producer: counter = register1 (counter = 6)
consumer: counter = register2 (counter = 4)
n Il valore di counter potrebbe essere o 4 o 6, mentre il
valore corretto dovrebbe essere 5.
Sistemi Operativi
P.Trunfio – R.Ortale
5
Race Condition
n Race condition: la situazione in cui più processi
accedono e manipolano dati condivisi in modo
concorrente. Il valore finale dei dati condivisi dipende
da quale processo ha finito per ultimo.
n Per eliminare le race condition, i processi concorrenti
devono essere sincronizzati.
Sistemi Operativi
P.Trunfio – R.Ortale
Il problema della sezione critica
n n processi che competono per usare dati condivisi.
n Ciascun processo ha un segmento di codice, chiamato
sezione critica, nel quale i dati condivisi sono acceduti.
n Problema: garantire che quando un processo è in
esecuzione nella sua sezione critica, nessun altro
processo sia autorizzato ad eseguire la propria
sezione critica.
Sistemi Operativi
P.Trunfio – R.Ortale
6
Soluzione al problema della sezione critica
Devono essere soddisfatti i seguenti requisiti:
1) Mutua esclusione. Se il processo Pi è in esecuzione nella propria
sezione critica, nessuna altro processo può essere in esecuzione
nella sua sezione critica.
2) Progresso. se nessun processo è in esecuzione nella propria
sezione critica, allora soltanto i processi che cercano di entrare
nella sezione critica partecipano alla decisione di chi entrerà
davvero, e questa decisione deve avvenire in un tempo finito.
3) Attesa limitata. Deve esistere un limite nel numero di volte che altri
processi sono autorizzati ad entrare nelle rispettive sezioni critiche
dopo che un processo Pi ha fatto richiesta di entrare nella propria
sezione critica e prima che quella richiesta sia soddisfatta.
Ø Si assume che ciascun processo esegua a velocità non nulla
Ø Nessuna assunzione deve essere fatta sulla velocità relativa degli n
processi.
Sistemi Operativi
P.Trunfio – R.Ortale
Sezione critica: soluzioni
n Soltanto 2 processi, P0 e P1
n Struttura generale del processo Pi
while (true) {
entry section
sezione critica
exit section
sezione non critica
}
n I processi possono far uso di variabili condivise per
sincronizzare le loro azioni.
Sistemi Operativi
P.Trunfio – R.Ortale
7
Algoritmo 1
n Variabili condivise:
F int turn;
F Inizialmente turn = 0
F Quando turn = i ⇒ Pi può entrare in esecuzione
nella propria sezione critica
n Processo Pi
while (true) {
while (turn != i) ;
sezione critica
turn = j;
sezione non critica
}
n Soddisfa la condizione della mutua esclusione, ma non
quella del progresso (richiede una stretta alternanza dei
processi)
Sistemi Operativi
P.Trunfio – R.Ortale
Algoritmo 2
n Variabili condivise:
F boolean flag[] = new boolean[2];
F Inizialmente flag[0] e flag[1] sono false.
F Quando flag[i] = true ⇒ Pi è pronto ad entrare nella
sua sezione critica
n Processo Pi
while (true) {
flag[i] = true;
while (flag[j]) ;
sezione critica
flag[i] = false;
sezione non critica
}
n Soddisfa la condizione della mutua esclusione, ma non
quella del progresso
Sistemi Operativi
P.Trunfio – R.Ortale
8
Algoritmo 3
n Usa le variabili condivise degli algoritmi 1 e 2.
n Processo Pi
while (true) {
flag[i] = true;
turn = j;
while (flag[j] && turn == j) ;
sezione critica
flag[i] = false;
sezione non critica
}
n Soddisfa tutti e tre i requisiti; tuttavia vale solo per due
processi.
Sistemi Operativi
P.Trunfio – R.Ortale
Algoritmo del Fornaio (1)
Sezione critica per n processi:
n Prima di entrare nella sezione critica, il
processo riceve un numero. Il possessore del
numero più piccolo entra nella sezione critica.
n Se i processi Pi e Pj ricevono lo stesso numero,
se i < j, allora Pi è servito prima; altrimenti Pj è
servito prima.
n Lo schema di numerazione genera sempre
numeri in ordine crescente; ad esempio:
1,2,3,3,3,3,4,5...
Sistemi Operativi
P.Trunfio – R.Ortale
9
Algoritmo del Fornaio (2)
n La notazione < indica l’ordinamento lessicografico tra
coppie del tipo: (ticket #, process id #)
F (a,b) < (c,d) se a < c oppure a == c && b < d
F max (a0,…, an-1) è un numero k, tale che k ≥ ai
per i : 0,…, n – 1
n Dati condivisi
boolean choosing[] = new boolean[n];
int number[] = new int [n];
Le strutture dati sono inizializzate a false e 0
rispettivamente
Sistemi Operativi
P.Trunfio – R.Ortale
Algoritmo del Fornaio (3)
while (true) {
choosing[i] = true;
number[i] = max(number[0], number[1], …, number [n – 1])+1;
choosing[i] = false;
for (j = 0; j < n; j++) {
while (choosing[j]) ;
while ((number[j] != 0) && ( (number[j],j) < (number[i],i) ) ;
}
sezione critica
number[i] = 0;
sezione non critica
}
Sistemi Operativi
P.Trunfio – R.Ortale
10
Soluzioni hardware per la sincronizzazione
n Controlla e modifica atomicamente il contenuto di una
parola.
boolean TestAndSet (boolean &target) {
boolean rv = target;
target = true;
return rv;
}
Sistemi Operativi
P.Trunfio – R.Ortale
Mutua esclusione con Test-and-Set
n Dati condivisi:
boolean lock = false;
n Processo Pi
while (true) {
while (TestAndSet(lock)) ;
sezione critica
lock = false;
sezione non critica
}
Sistemi Operativi
P.Trunfio – R.Ortale
11
Hardware di Sincronizzazione
n Scambia atomicamente il valore di due variabili.
void Swap (boolean &a, boolean &b) {
boolean temp = a;
a = b;
b = temp;
}
Sistemi Operativi
P.Trunfio – R.Ortale
Mutua Esclusione con Swap
n Dati condivisi:
boolean lock, key; // lock inizializzato a false
n Processo Pi
while (true) {
key = true;
while (key == true)
Swap(lock,key);
sezione critica
lock = false;
sezione non critica
}
Sistemi Operativi
P.Trunfio – R.Ortale
12
Semafori
n Strumento di sincronizzazione che in determinate
implementazioni non richiede busy waiting.
n Semaforo S: variabile intera
n Può essere acceduta esclusivamente attraverso due
operazioni indivisibili (atomiche):
wait (S):
while (S <= 0) ; /* do no-op */
S--;
signal (S):
S++;
Sistemi Operativi
P.Trunfio – R.Ortale
Sezione critica di n Processi
n Dati condivisi:
semaforo mutex; // inizialmente mutex = 1
n Processo Pi :
while (true) {
wait(mutex);
sezione critica
signal(mutex);
sezione non critica;
}
Sistemi Operativi
P.Trunfio – R.Ortale
13
Implementazione dei Semafori
n Definiamo un semaforo:
class Semaforo {
int value;
List listaProcessi = new List ();
}
n Assumiamo che esistano le seguenti operazioni:
F block() sospende il processo che la invoca.
F wakeup(P) riprende l’esecuzione del processo
bloccato P.
Sistemi Operativi
P.Trunfio – R.Ortale
Operazioni associate ai Semafori
Supponiamo che sia dichiarato il Semaforo S:
wait(S):
S.value--;
if (S.value < 0) {
aggiunge questo processo a S.listaProcessi;
block();
}
signal(S):
S.value++;
if (S.value <= 0) {
rimuove un processo P da S.listaProcessi;
wakeup(P);
}
Sistemi Operativi
P.Trunfio – R.Ortale
14
Semaforo come strumento generale di
sincronizzazione
n Esegue B in Pj solo dopo che A esegue in Pi
n Usa il semaforo flag inizializzato a 0
n Codice:
Pi
M
A
signal(flag)
Pj
M
wait(flag)
B
Sistemi Operativi
P.Trunfio – R.Ortale
Deadlock e Starvation
n Deadlock – due o più processi sono indefinitamente in
attesa per un evento che può essere causato da uno
soltanto dei processi in attesa.
n Siano S e Q due semafori inizializzati a 1
P0
P1
wait(S);
wait(Q);
wait(Q);
wait(S);
M
M
signal(S);
signal(Q);
signal(Q)
signal(S);
n Starvation – blocking indefinito. Un processo A potrebbe
non essere mai rimosso dalla coda del semaforo in cui è
sospeso.
Sistemi Operativi
P.Trunfio – R.Ortale
15
Due tipi di semafori
n Semaforo contatore – valore intero che può spaziare su
un dominio illimitato.
n Semaforo binario – valore intero che può valere solo 0 e
1; può essere più semplice da implementare.
n E’ possibile implementare un semaforo contatore usando
semafori binari.
Sistemi Operativi
P.Trunfio – R.Ortale
16