Lezione 7 Comunicazione tra processi
Introduzione La soluzione sw al problema della mutua esclusione è abbastanza complessa Algoritmo di Peterson La soluzione hw mediante disabilitazione degli interrupt non è adeguata per programmi utente Codice dal comportamento oscuro, scarsa efficienza, inutile nei sistemi multiprocessore Una soluzione migliore può essere ottenuta con un certo supporto da parte del linguaggio macchina del sistema su cui operiamo 2
Introduzione Si associa ad una sezione critica una chiave di accesso, tipicamente una variabile booleana Un processo che intende entrare in sezione critica deve prima ottenere la chiave, tenerla per tutto il tempo in cui rimane nella sezione critica, indi rilasciarla all uscita LOCK(KEY) equivale a ENTER REGION Sezione critica UNLOCK(KEY) equivale a LEAVE REGION 3
Introduzione Questa soluzione funziona solo se un processo, nel momento in cui ispeziona il contenuto della chiave e la trova disponibile, può bloccarla istantaneamente, senza essere interrotto Diversamente sarebbe la stessa soluzione vista con i lock condivisi che davano origine a condizioni di contesa 4
Test and Set Lock I primi a notare questa necessità furono i progettisti dell OS/360 Aggiunsero nel linguaggio macchina del sistema l istruzione TEST AND SET LOCK (TSL) 5
TSL TSL opera nel seguente modo Sintassi TSL register, flag Semantica register fl flag /* copia in register il valore corrente di flag */ flag fl 1 /* assegna 1 a flag */ con la garanzia di indivisibilità o atomicità delle due operazioni sono eseguite come se si trattasse di un unica istruzione 6
TSL Disponendo dell istruzione TSL, le primitive LOCK e UNLOCK (equivalenti a enter_region, leave_region) possono essere così implementate LOCK(KEY) lock: tsl register,key copia key in register e key fl1 cmp register,$0 key era <> 0? jnz lock se sì torna a lock ret entra in sez. critica UNLOCK (KEY) move key, $0 ret 7
Osservazioni Vantaggi di soluzioni basate su istruzioni speciali Si applicano a qualunque numero di processi, con singolo processore o multipli a memoria condivisa Semplici e facili da verificare Si può associare una variabile a ciascuna sezione critica 8
Osservazioni Svantaggi di soluzioni basate su istruzioni speciali Busy wait Starvation possibile a causa della scelta del prossimo processo da eseguire quando uno lascia la sezione critica Deadlock per inversione di priorità se il processo in sezione critica P1 viene interrotto e la CPU assegnata ad un processo P2 con priorità superiore che cerca di entrare, non può a causa di P1 che però non può eseguire avendo priorità inferiore a P2, che è attivo in busy wait 9
Semafori I meccanismi di programmazione concorrente sinora visti hanno alcuni limiti Basati sul busy waiting di processi Non facilmente utilizzabili in tutti i problemi di programmazione concorrente (sincronizzazione e cooperazione) Per superare queste limitazioni nel 1965 Dijkstra propone un nuovo meccanismo da utilizzare per scrivere programmi concorrenti SEMAFORI tipo particolare di segnale del quale un processo resta in attesa 10
Semafori I semafori sono delle variabili intere devono essere condivise tra più processi possono assumere come valore 0 e 1 in questo caso parliamo di semafori binari un intero >= 0 in questo caso parliamo di semafori generalizzati Le operazioni definite sui semafori sono due P(sem) o Down(sem) V(sem) o Up(sem) A queste si aggiunge l inizializzazione semaforo = valore 11
Semafori binari Le operazioni Down(sem) e Up(sem) hanno la seguente semantica Down(sem): if(sem == 0)then wait on sem; else sem = 0; Up(sem): if (some process is waiting on sem) then awake it else sem = 1; Il sistema ne garantisce l atomicità eseguite come se fossero un unica istruzione macchina 12
Semafori binari I processi non attendono più in busy wait A ciascun semaforo è associata una coda in cui vengono posti i processi bloccati sul particolare semaforo La disciplina di gestione della coda non è specificata nella definizione dei semafori solitamente FIFO I processi sono risvegliati dalla coda quando un altro processo esegue V sul semaforo su cui sono bloccati 13
Semafori binari Con i semafori binari il problema della mutua esclusione tra n processi può essere risolto molto facilmente Ogni processo esegue la sequenza DOWN(sem) /* entrer_region */ Sezione critica UP(sem) /* leave_region */ Il primo che esegue Down(sem) entra in regione critica 14
Semafori binari I semafori binari possono anche essere usati per sincronizzare due o più processi Determinare una specifica sequenza di esecuzione Esempio semaphore S1 = 1; semaphore S2 = 0; semaphore S3 = 0; P1 P2 P3 down(s1) down(s2) down(s3) : : : up(s2) up(s3) up(s1) 15
Semafori binari I semafori binari ben si prestano a modellare l interazione tra una periferica e il gestore dell interrupt Siano sem e sem1 due semafori binari inizializzati a 0 Periferica: inizializzazione down(sem) : up(sem1) 16 Gestore interrupt: operazioni varie up(sem) down(sem1) :
Il problema del produttoreconsumatore Il produttore è un processo che produce elementi che vengono consumati da un processo consumatore Produttore e consumatore possono eseguire concorrentemente grazie ad un buffer il produttore vi inserisce i suoi elementi e il consumatore li preleva Il produttore non deve inserire elementi in celle del buffer già occupate Il consumatore non deve consumare elementi non ancora prodotti 17
Prod-cons con buffer infinito 18
Schema prod-cons con buffer infinito Semaphore sem = 0; int buffer[infinito]; void prod (void) { int in = 0; int item; while (TRUE) { produci(&item); buffer[in]= item; in = in+1; up(sem) } } void cons (void) { int out = 0; int item; while (TRUE) { down(sem); item = buffer[out]; out = out+1; consuma(&item); } } 19
Domande Il semaforo utilizzato nel precedente programma è un semaforo binario o un semaforo generalizzato? Quale problema si presenta nel momento in cui abbiamo a che fare con più processi produttori? 20
Esercizio area occupata Modificare il caso con buffer infinito al caso di buffer circolare 21
I semafori generalizzati Le operazioni Down(sem) e Up(sem) hanno la seguente semantica Down(sem): if(sem == 0)then wait on sem; else sem = sem - 1; Up(sem): if (some process is waiting on sem) then awake it else sem = sem + 1; Il sistema ne garantisce l atomicità 22
N prod, M cons, buffer infinito Semaphore sem =0, mutex =1; int buffer[infinito]; void prod (void) { int i = 0; int item; while (TRUE) { produci(&item); down (mutex); buffer[i] = item; i = i+1; up (mutex) up(sem) } } 23 void cons (void) { int i = 0; int item; while (TRUE) { down(sem); down(mutex); item = buffer[i]; i = i+1; up(mutex); consuma(&item); } }
N prod, M cons, buffer infinito sem svolge funzioni di sincronizzazione tra produttori e consumatori I consumatori non consumano fino a che non ci sono elementi prodotti Notare che i produttori non sono soggetti ad alcun vincolo buffer infinito mutex garantisce la mutua esclusione nell accesso a buffer 24
N prod, M cons, buffer finito empty: impedisce scritture nel buffer pieno e letture dal buffer vuoto mutex: garantisce la mutua esclusione su buffer 25
Problemi implementativi Dal punto di vista della struttura dati, un semaforo è: typedef struct { int valore; } pcb *next; semaphore; Le primitive Up e Down vengono implementate come supervisor call 26
Problemi implementativi Le operazioni Down(sem) e Up(sem) Down(sem): if(sem == 0)then waiting on sem ; Up(sem): else sem = sem - 1; if (some process is waiting on sem) then awake it else sem = sem + 1; come si effettua questo test? 27
Problemi implementativi Down(sem): sem.valore=sem.valore 1; if(sem.valore < 0) then {aggiungi un processo a sem.next; metti il processo in waiting; } Up(sem): sem.valore=sem.valore + 1; if (sem.valore <=0) then {rimuovi un processo da sem.next; metti il processo in ready; } 28
Atomicità Problemi implementativi Su sistemi uniprocessore disabilitare interrupt Su sistemi multiprocessore disabilitare gli interrupt non basta Up e Down devono essere eseguiti come sezione critica, ad esempio: LOCK(lockbit) TSL o Peterson Down(sem) UNLOCK(lockbit) 29
Esercizio Problema dei lettori e scrittori Un insieme di processi condivide un file dal quale alcuni possono solo leggere i dati, altri solo scriverli Più lettori possono leggere simultaneamente Un solo scrittore per volta può scrivere Quando uno scrittore scrive, nessun lettore può leggere Diverso da Prod/cons i lettori non modificano i puntatori al buffer i produttori leggono i puntatori, gli scrittori no 30
Esercizio Sviluppare una soluzione al problema della corretta sincronizzazione degli accessi 1 scrittore, 1 lettore Accessi in mutua esclusione al file sia dello scrittore sia del lettore rispetto a questo 1 scrittore, n lettori n scrittori, n lettori Considerare chi ha priorità, lettori o scrittori 31
Esercizio Problema dei filosofi a cena 5 piatti di riso e 5 bastoncini sono disposti alternati a tavola 5 filosofi siedono ciascuno davanti ad un piatto la vita di un filosofo alterna momenti di attività intellettuale ai pasti, che consuma solo se riesce a prendere i due bastoncini ai suoi lati Scrivere un programma che permetta a ciascun filosofo di vivere, cioè pensare e mangiare alternativamente, e a due filosofi di mangiare simultaneamente 32