La (dai sistemi concorrenti ai sistemi distribuiti)
Mutua esclusione e sistemi concorrenti La nasce nei sistemi concorrenti abbiamo n processi che vogliono accedere ad una risorsa condivisa ogni processo esegue la sequenza di passi <non in sezione critica> <trying protocol> sezione critica <exit protocol> <non in sezione critica> Lo scheduler sceglie di volta in volta l istruzione da eseguire di un certo processo, la sequenza scelta è chiamata schedule (accesso alla risorsa condivisa) (una volta uscito puo ricominciare)
sistemi concorrenti Caratteristiche di un sistema concorrente-- NO DISTRIBUITO!-- Modello di Dijkstra i processi comunicano leggendo e scrivendo variabili condivise la lettura e scrittura di una variabile è un azione atomica (non interrompibile) Nessuna assunzione sul tempo che impiega ogni processo ad eseguire un azione atomica (es. uno molto lento contro un altro molto veloce)
Mutua esclusione\specifica Definizione del problema in termini di tre proprietà: ME (Mutua Esclusione): due processi non possono essere nelle loro sezioni critiche contemporaneamente ND (No Deadlock): se un processo rimane bloccato nella sua trying section, ci sono uno o piu processi che riescono ad accedere alla sezione critica NS (No Starvation) [OPTIONAL]: nessun processo puo rimanere bloccato nella trying section per sempre NS implica ND
Algoritmo di Dijkstra (1965) Shared variables b[1,..n]: array of Boolean, initially all true c[1,..n]: array of Boolean, initially all true k: integer in range 1,..N, initially any value in its range Local variables j: integer in range 1,..N % il processo si prenota % trying protocol ciclo della sentinella exit protocol
Un possibile schedule s1 (initially k=4) P1 b[1]:= false if k 1 then begin c [1]:= true P2 b[2]:= false if k 2 then begin c [2]:= true P3 if b[4] then k:=1 if b[4] then k:=2 b[2]:= false if k 3 then begin c [3]:= true if b[4] then k:=3
cosa è successo? alla fine di questa parte di schedule la situazione è la seguente: la prossima istruzione da eseguire per tutti i processi è l istruzione Li4 il valore di k=3 A questo punto la seconda parte della trying section deve assicurare che solo uno tra P1, P2 e P3 entri in sezione critica...sembra che P3 abbia la precedenza, ma in realtà l ordine di entrata lo dice lo scheduler...
un possibile schedule s1-a P1 c[i]:=false for j:= 1 to n do if i j and not c[j] then goto Li1 sezione critica c[i]:=b[i]:= true; P2 c[i]:= false for j:= 1 to n do if i j and not c[j] then goto Li1 sezione critica c[i]:=b[i]:= true; P3
un possibile schedule s1-a P1 P2 P3 c[i]:= false for j:= 1 to n do if i j and not c[j] then goto Li1 sezione critica c[i]:=b[i]:= true;
un possibile schedule s1-b P1 c[i]:= false if i j and not c[j] then goto Li1 c[i]:= true P2 c[i]:= false if i j and not c[j] then goto Li1 c[i]:= true P3 c[i]:= false if i j and not c[j] then goto Li1... c[i]:= false
che cosa è successo? A questo punto entra in gioco il valore k, mentre P1 e P2 rimangono bloccati all istruzione Li1 (anche se lo schedule dà la possibilità a P1 e P2 di eseguire un istruzione, P1 e P2 non eseguono nulla), P3 salta direttamente alla riga Li4 (k=3), pone c[3]=false ed entra in sezione critica (per gli altri due c è pari a true) quando P3 esce dalla sezione critica allora b[3] viene posto di nuovo pari a true e ciò sblocca i processi P1 e P2 ancora bloccati all istruzione Li1 ora l algoritmo si ripete allo stesso modo per P1 e P2
prova di ME Per assurdo: supponiamo esista uno schedule S1 per cui due processi i e j sono in sezione critica concorrentemente. Ciò implica che: i ha eseguito con successo Li4, cioè ha trovato c[j]=true implica i ha eseguito la terza linea di Li4 prima che j eseguisse la prima linea di Li4, cioè lo schedule S1 ha posto i. Li4-3 e poi j.li4-1 chiaramente in S1 sia anche i.li4-1 precede i.li4-3 (stesso processo) implica per transitività in S1 i.li4-1 precede j.li4-1
prova di ME Ora scambiando i e j e facendo lo stesso ragionamento otteniamo che: in S1 j.l4-1 precede i.l4-1 contraddizione OSSERVAZIONI: la ME è facilmente garantita da un uso opportuno della struttura dati c
prova di ND Per assurdo: supponiamo che un gruppo di processi D sono bloccati nella trying section e nessuno puo entrare nella sezione critica implica per ogni processo Pk in D abbiamo che b[k]=false. Suppponiamo ora che Pi sia l ultimo processo che ha fatto l assegnazione della variabile k (Li3). Pi appartiene a D altrimenti se potesse eseguire CS e quindi anche l exit protocol allora porrebbe b[k]=true. Se ciò fosse un altro processo Pj appartenente a D troverebbe b[k]=true e porrebbe a j il valore della variabile k. Poichè j appartiene a D (è bloccato) allora anche Pi appartiene a D
prova di ND Ogni processo Pk in D avrà prima o poi la variabile c[k]=false, questo perchè se pure l avevano a false poi grazie all esecuzione di Li4 ritornano con il goto Li1 a settare di nuovo la variabile c a true. Ogni processo Pk in D si va quindi a bloccare nel ciclo della sentinella L unico che salta il ciclo è Pi che va in sezione critica perchè tutti hanno la variabile c[k] uguale a true Ma se Pi va in sezione critica, non può appartenere a D. Contraddizione. OSSERVAZIONI: ND è garantita da un uso oppurtuno della variabile k
L algoritmo di Dijkstra e NS Domanda: un processo che setta con successo la variabile k quante volte puo eseguire l istruzione goto Li1 prima di entrare in sezione critica? Perchè NS non è soddisfatta? Fornire un particolare scenario in cui si viola NS
Sistemi concorrenti (ii) Abbiamo visto il modello concorrente definito da Dijkstra in cui è possibile che piu processi scrivano e leggano in modo atomico nella/dalla stessa variabile. Questo è un modello che astrae bene sistemi con una sola memoria fisica ma non sistemi multiprocessori con memoria locali In sistemi multiprocessori potremmo avere copie di una stessa variabile su macchine diverse Nota che l algoritmo funziona basandosi di fatto su meccanismi hardware che organizzano un accesso in alla memoria fisica (variabile k)
Modello di Lamport i processi comunicano leggendo e scrivendo variabili condivise la lettura e la scrittura di una variabile non è un azione atomica. Uno scrittore potrebbe scrivere mentre un altro processo sta leggendo Ogni variabile condivisa è di proprietà di un processo: solo questo processo puo scrivere la sua variabile condivisa, gli altri possono solo leggere Nessun processo puo emettere due scritture concorrentemente La velocità di esecuzione dei processi sono non correlate. In un tempo infinito ogni processo esegue un numero infinito di passi elementari mentr in un tempo finito nè esegue un numero finito
Algoritmo del Panettiere (Lamport 1975) Shared variable num[1,..n]: array of integer, initially all 0 choosing[1,..n]: array of Boolean, initially all false %process i owns num[i] and choosing[i]% Local variable j: integer in range 1,..N repeat 1 NCS 2 choosing[i]:= true trying protocol exit protocol 3 num[i]:= 1+ max {num[j] : n j 1} %DOORWAY% 4 choosing[i]:= false 5 for j:= 1 to n do begin 6 while choosing[j] do skip 7 while num[j] 0 and {num[j], j } < {num[i],i} do skip %BAKERY% 8 end 9 CS 10 num[i]:=0; forever
Panettiere - doorway nella DOORWAY, ogni processo Pi che entra nella trying section lo segnala agli altri grazie alla variabile choosing[i]. Quindi deve prendere un numero di prenotazione, per farlo PRIMA legge tutti i numeri scelti dagli altri prima di lui, quindi prende il massimo e aggiunge uno ATTENZIONE: altri insieme a Pi possono accedere alla doorway concorrentemente!
Una run R1 possibile per la doorway P1 choosing[i]:= true P1 legge sicuramente il valore scritto da P2 perchè non vi è concorrenza fra le due operazioni num[1]:=1+max {num[j]:3 j 1 P1 potrenne leggere come no il valore finale scritto da P3 perchè le due operazioni sono concorrenti, in questa run non lo legge NUM[1]=2 P2 choosing[i]:= true NUM[2]=1 num[2]:=1+max {num[j]:3 j 1 P3 choosing[i]:= true num[3]:=1+max {num[j]:3 j 1 NUM[3]=2 durante la concorrenza, P3 potrebbe leggere il valore finale scritto da P2 oppure no, in questa run lo legge
Panettiere - bakery Una volta uscito dalla doorway il processo Pi deve assicurarsi che tra i processi che sono in attesa lui è il prossimo ad entrare nella sezione critica, i cicli while a line 7 e 8 hanno esattamente questo scopo: while choosing[j] do skip: Pi si assicura che ogni processo che concorrentemente con lui è acceduto alla doorway completi la scrittura del numero: finchè c è qualcuno che sta ancora scegliendo, Pi aspetta while num[j] 0 and {num[j], j } < {num[i],i} do skip: il processo Pi si assicura che tutti i processi che concorrentemente sono in procinto di accedere all CS abbiano un numero piu grande del suo oppure uguale ma identificativo di processo piu grande: finchè c è qualcuno con un numero più piccolo, Pi aspetta
Una run R1 possibile per il bakery P1 choosing[i]:= true NUM[1]=2 while su num NUM[1]=0 choosing[i]:= false P2 NUM[2]=1 choosing[i]:= false while su choosing NUM[2]=0 while su num P3 NUM[3]=2 while su choosing choosing[i]:= false while su num qui si sblocca la while su choosing per P2 e P3, si noti come grazie a questa while i tre processi sono riallineati prima di comparare i numeri tra di loro
Il panettiere e le sue proprietà ME deriva dalla seguente proprietà se un processo i è nella doorway ed un processo j è nella bakery section allora {num[j], j } < {num[i],i}. Quindi se due processi i e j sono nella CS contemporaneamente allora per la predecente proprietà otteniamo {num[i],i } < {num[j],j} e {num[j], j } < {num[i],i} chiaramente un assurdo (La prova formale, in realtà è più complicata...) NS è garantita dal fatto che nessun processo attende per sempre poichè prima o poi avrà il numero di attesa più piccolo L algoritmo del panettiere gode anche della seguente proprietà: FCFS(first-Come-First-Served): Se Pi entra nella sezione bakery prima che Pj entra nella doorway allora Pi entrerà in sezione critica prima di Pj Domande: indicare il range della variabile num[i] nell algoritmo del panattiere provare formalmente che l algoritmo del panettiere assicura FCFS perchè non vale la seguente (più intuitiva) nozione FCFS: se il Pi entra nella doorway prima di Pj allora Pi entrerà in sezione critica prima di Pj