Slide dal Dipartimento di Scienze Matematiche, Informatiche e Fisiche sulla sincronizzazione. Il Pdf, una presentazione didattica di livello universitario in Informatica, esplora i processi concorrenti, il problema della sezione critica e le sue soluzioni, inclusi semafori e monitor.
Mostra di più39 pagine


Visualizza gratis il Pdf completo
Registrati per accedere all’intero documento e trasformarlo con l’AI.
Sistemi Operativi e Laboratorio A. Formisano Dipartimento di Scienze Matematiche, Informatiche e Fisiche Anno Accademico 2024-25 Sistemi Operativi e Lab. 24/25 A. Formisano, DMIF
Sistemi Operativi e Lab. 24/25 A. Formisano, DMIF
In condizioni normali, un moderno sistema operativo deve gestire più processi contemporaneamente in esecuzione
Sistemi Operativi e Lab. 24/25 A. Formisano, DMIF
L'accesso contemporaneo da parte di due processi a dati condivisi può essere problematico:
Sistemi Operativi e Lab. 24/25 A. Formisano, DMIF
In questa breve descrizione abbiamo introdotto le nozioni fondamentali che studieremo nelle prossime lezioni: Sezione Critica (SC) Una sezione di codice che legge/scrive dati condivisi Race Condition Una situazione in cui l'esecuzione concorrente di una sezione critica, da parte di più processi, porta a risultati dipendenti dall'ordine in cui i processi alternano l'esecuzione delle loro istruzioni (Ciò è potenziale fonte di inconsistenze dei dati)
Sistemi Operativi e Lab. 24/25 A. Formisano, DMIF
Mutua Esclusione Meccanismo con cui si evitano le race condition assicurando l'accesso esclusivo ai dati. (Un processo deve essere "autorizzato" ad entrare in una sezione critica) Deadlock (o blocco critico) Situazione in cui dei processi sono permanentemente bloccati perchè in attesa vicendevole del rilascio di risorse Starvation Situazione in cui ad un processo che ha richiesto l'accesso ad una sezione critica non viene mai permesso di evolvere perchè vengono sempre servite le richieste di altri processi
Sistemi Operativi e Lab. 24/25 A. Formisano, DMIF
Due processi collaborano nello svolgere un semplice compito: un processo produttore produce dei dati che vengono utilizzati da un processo consumatore. Lo scambio dei dati avviene tramite un buffer condiviso. Ecco le definizioni:
#define BUFFER_SIZE 10 / / dimensione del buffer typedef struct { . . . } item; item buffer [BUFFER_SIZE] ; / / array circolare int in = 0; / / posizione in cui scrivere int out = 0; / / posizione da cui leggere int counter = 0; / / num. di record memorizzati
Sistemi Operativi e Lab. 24/25 A. Formisano, DMIF
item nextProduced; while (1) { / / loop forever while (counter == BUFFER_SIZE) ; /* non fa niente (busy waiting! !! ) */ buffer [in] = nextProduced; in = (in+1) % BUFFER_SIZE; counter++; } item nextConsumed; while (1) { / / loop forever while (counter == 0) ; /* non fa niente (busy waiting! !! ) */ nextConsumed = buffer [out] ; out = (out+1) % BUFFER_SIZE; counter --; }
Sistemi Operativi e Lab. 24/25 A. Formisano, DMIF
Sistemi Operativi e Lab. 24/25 A. Formisano, DMIF
Consideriamo una specifica risorsa condivisa e le sezioni critiche ad essa relative presenti nei codici eseguiti da diversi processi. Una soluzione al problema della sezione critica deve garantire:
Sistemi Operativi e Lab. 24/25 A. Formisano, DMIF
Si ha quindi che:
Sistemi Operativi e Lab. 24/25 A. Formisano, DMIF
La soluzione del problema consiste nel progettare un protocollo che se adottato dai processi garantisca che l'effetto globale delle loro azioni non dipenda dal modo in cui le queste si inframezzano. Uno schema generale per una soluzione prevede che:
Sistemi Operativi e Lab. 24/25 A. Formisano, DMIF
Consideriamo due processi P0 e P1 con questa semplice struttura: ... sezione non critica sezione d'ingresso sezione critica sezione d'uscita sezione non critica P0 e P1 condivideranno delle variabili al fine di sincronizzarsi. Cerchiamo la soluzione:
Sistemi Operativi e Lab. 24/25 A. Formisano, DMIF
Usiamo una variabile turno per indicare chi ha il diritto di ingresso. Ecco il codice del processo Pi (l'altro è Pj): int turno = 0; /* turno=i indica ok per Pi */ do { . sezione non critica ... while (turno != i) ; / / attesa del proprio turno . sezione critica ... turno = j; / / permetto all'altro di entrare . . sezione non critica ... } while (1) ;
Sistemi Operativi e Lab. 24/25 A. Formisano, DMIF
Per verificare se è una soluzione corretta dobbiamo assicurarci che garantisca le tre proprietà: mutua esclusione: OK progresso e attesa limitata NO !!! infatti:
Sistemi Operativi e Lab. 24/25 A. Formisano, DMIF
Usiamo due flag booleani per indicare l'interesse di un processo a entrare nella SC. Ecco il codice del processo Pi (l'altro è Pj): boolean flag [2] ; / * flag [i]=true indica che Pi vuole entrare inizialmente flag[0]=flag[1]=false * / do { . sezione non critica ... flag [i] = true; / / dichiara il suo interesse while (flag[j] ) ; / / attesa del proprio turno ... sezione critica ... flag[i] = false; £ / / dichiara la fine dell'interesse . . sezione non critica ... while (1) ; }
Sistemi Operativi e Lab. 24/25 A. Formisano, DMIF
In questo caso un processo può entrare in SC più volte consecutive. Ma le tre proprietà NON sono tutte garantite: mutua esclusione: OK progresso e attesa limitata NO !!! infatti:
Sistemi Operativi e Lab. 24/25 A. Formisano, DMIF
Usiamo sia la variabile turno che i due flag per dichiarare l'interesse a entrare nella SC. Ecco il codice del processo Pi (l'altro è Pi): boolean flag [2] ; int turno; do { . sezione non critica ... flag[i] = true; // dichiara il suo interesse turno = j; / / assume che sia il turno dell'altro / / e gli offre l'occasione di entrare while (flag[j] and turno == j) ; / / attesa del proprio turno . sezione critica ... flag [i] = false; // fine dell'interesse .... sezione non critica ... } while (1) ; Vi convince? Perchè?
Sistemi Operativi e Lab. 24/25 A. Formisano, DMIF