44
Sistemi Operativi II Programmazione Concorrente: Concetti di Base

Programmazione Concorrente: Concetti di Baseunina.stidue.net/Universita' di Trieste/Ingegneria Industriale e... · su alcune istruzioni l’esecutore è libero di scegliere quali

  • Upload
    lyque

  • View
    222

  • Download
    0

Embed Size (px)

Citation preview

Sistemi Operativi II

Programmazione Concorrente:Concetti di Base

Programmi e Processi

Programma: descrizione statica, ovvero che non cambia nel tempo, di un processoProcesso: concetto dinamico, ovvero che evolve nel tempo

un processo scaturisce con l’esecuzione di un programma da parte di un esecutoread un medesimo programma possono corrispondere molteplici processi

Un processo per poter avanzare necessita di risorse, prima tra tutte, l’esecutore

Risorse

Servono per l’avanzamento dei processiL’esecutore è una di queste risorse, ma ne esistono di molti altri tipiConsideriamo, per concretezza, esempi di risorse hardware, ma ragionamenti analoghi si possono fare anche con altri tipi di risorse, ad esempio risorse software

Prerilasciabilità delle Risorse

Prerilasciabilisi possono sottrarre al processo che le sta usando senza causare il fallimento dell’esecuzione in attorisorsa non seriale: molteplicità della risorsa > 1

es. memoria virtuale, processore virtuale

Non Prerilasciabilise sottratte al processo che le sta usando, l’esecuzione falliscerisorse seriali; molteplicità = 1

es. stampante, masterizzatore

Molteplicità di una risorsa: numero massimo di processi che la possono usare concorrentemente

Risorse di Molteplicità Finita

Per le risorse di molteplicità finita, affinché l’utilizzo risulti costruttivo, è necessario che gli accessi alla risorsa siano controllati

Si prevede Un gestore della RisorsaUn protocollo di accesso alla Risorsa

richiesta ed ottenimento della risorsautilizzo della risorsa

rilascio della risorsa

Programmazione Sequenziale

La programmazione è di solito insegnata con riferimento ad un esecutore sequenzialeUn esecutore sequenziale svolge una sola azione alla volta sulla base di un programma sequenziale L’esecuzione di un programma sequenziale origina un processo sequenziale che conferisce un ordinamento totale alle azioni eseguite

La programmazione di un esecutore concorrente, ovvero in grado di eseguire più istruzioni contemporaneamente, sebbene più difficile di quella tradizionale, ha forti motivazioni didattiche e pratiche

Programmazione Concorrente: Motivazioni

Migliorare la comprensione di un SO che regola diverse attività paralleleSfruttare le prestazioni ottenibili da architetture multi-processor

un programma sequenziale non giova di una architettura parallela

Migliorare la reattività delle applicazioni all’input dell’utente durante lunghe operazioni di I/O o di elaborazioneLa maggiore naturalezza con la quale si possono scrivere alcune tipologie di applicazioni (server, robotica, giochi, simulazioni di attività concorrenti)

Utilizzo dei Processori: Applicazione mono-thread

Utilizzo dei Processori: Applicazione multi-thread

Istruzione ed Area MemoriaPer ragionare a vari livelli di granularità, consideriamo astrattamente i due concetti di istruzione ed area di memoria

Istruzione; alcune possibili esemplificazioni:istruzione macchinaistruzione firmwareuno statement javaun metodo di una classe javaun intero programmauna stored-procedure di un DBMSla scrittura di un blocco del gestore della concorrenza di un DBMS

Area di Memoria; alcune possibili esemplificazioni:un bit, un byte, una parola macchinaun campo di una struttura dati, una struttura dati interaun attributo, una tupla, una tabella, un intero dbun blocco di un dispositivo di memoria secondaria

Processi Paralleli o Concorrenti

Un processo sequenziale definisce un ordinamento totale sulle istruzioniUn processo parallelo definisce un ordinamento parziale sulle istruzioni

su alcune istruzioni l’esecutore è libero di scegliere quali iniziare prima e/o di eseguirle contemporaneamente

Esempio: consideriamo un banale programma per calcolare e stampare le prime quattro potenze di un valore X. Si supponga di disporre di tre sole tipologie di istruzione:

leggi <variabile>scrivi <variabile><variabile> ← <variabile> * <variabile>

Diagramma delle Precedenze

Algoritmo parallelo

Algoritmo sequenziale

leggi X

begin1. leggi X;2. scrivi X;3. X2 ← X * X;4. scrivi X2;5. X3 ← X2 * X;6. scrivi X3;7. X4 ← X2 * X2;8. scrivi X4;

end

X2 ←X*Xscrivi X

scrivi X2 X3 ←X2*X

scrivi X3

scrivi X4

X4←X2*X2

Esercizi

Esercizio: costruire un diagramma delle precedenze che esprima il massimo grado di parallelismo nel calcolo delle seguenti espressioni sullo stile dell’esempio appena visto:

a) (A+B)*(C+D)

b) A*X^4+B*X^3+C*X^2+D*X+E

c) ( -B-SQRT(B^2-4*A*C) )/(2*A)

Esecuzioni Sequenziale e Parallele

Sia i una generica istruzione, in generale può essere divisibile in istruzioni più elementariSiano Ii e Fi gli eventi di inizio e fine esecuzioneDate due istruzioni a e b consideriamo i 6 possibili ordinamenti in cui occorrono i quattro eventi Ia, Fa, Ib,Fb

Ia Ib Fa Fb

Ia Fa Ib Fb Ia Ib Fb Fa

Ib Fb Ia Fa Ib Ia Fa Fb

Ib Ia Fb Fa

esecuzioni sequenziali esecuzioni parallele

Sequenze di Esecuzione Ammissibili

Una sequenza di esecuzione ammissibile è una sequenza di questi eventi che rispetta i vincoli espressi dal diagramma delle precedenzeAd un certo diagramma delle precedenze corrispondono molteplici sequenze di esecuzione ammissibiliAd es., con riferimento al precedente diagramma:

Ii1Fi1Ii2Ii3Fi2Fi3Ii4Ii7Ii5Fi5Fi7Fi4Ii6Fi6Ii8Fi8

Sequenze di Interleaving

Un caso speciale ma rilevante di sequenza di esecuzione ammissibile; consideriamo:

un solo esecutore fisico istruzioni indivisibilidue processi sequenziali A e B con istruzioni

a1a2a3a4…

b1b2b3b4…

Diciamo sequenza di interleaving la sequenza scelta dall’esecutore, ad esempio:

a1b1b2a2b3a3a4b4…

Analogamente per tre o più processi

Processori Virtuali

Nei sistemi operativi moderni, molteplici esecutori virtuali possono essere implementati con uno o più processori fisici attraverso tecniche di context-switching

In base al numero di processori fisici disponibili ed al numero di processi esistenti, risultano possibili varie situazioni per far avanzare concorrentemente i processi

interleavingoverlappinguna combinazione di queste due

Overlapping ed Interleaving

L’esecutore può eseguire più istruzioni concorrentemente mediante

overlapping

interleaving

combinazione

CPUCPU00tPa

CPUCPU11tPb

tCPUCPU00 CPUCPU00

t

CPUCPU0 CPUCPU0Pa0 0

Pb

CPUCPU00CPUCPU11

CPUCPU11CPUCPU00

tPa

Pbt

Fork & Join

Per esprimere attività concorrenti si possono usare diversi costrutti. Nella forma più semplice, bastano:

process_id = fork <programma_id>crea un processo figlio di quello attuale mediante l’attivazionedel programma specificato. Restituisce l’identificatore del processo figlio appena creato. Padre e figlio continuano indipendentemente il loro avanzamento. join process_idil processo corrente rimane bloccato sino a quando non termina il processo specificato

In genere ciascun processo è dotato di proprie aree di memoria dati (record di attivazione) mentre il codice può essere condiviso. In questo caso si parla di programmi o procedure rientranti

Traduzione di un Diagramma delle Precedenze con fork & join

concurrent Procedure P1begin <corpo di P1>; endconcurrent Procedure P2begin <corpo di P2>; end…begin

P1;fork P2; fork P3;join P2; join P3;P4;

end

P1

P3 P2

P4

Esercizi

Esercizio: tradurre con fork e join il diagramma delle precedenze per il calcolo e la stampa delle prime quattro potenze di un dato numero.

Esercizio: disegnare il diagramma delle precedenze per il calcolo e la stampa progressiva delle prime N potenze di un dato numero; tradurre con fork e join il diagramma delle precedenze trovato. Ragionare sulla presenza del ciclo di iterazione, come esprimerlo ed interpretarlo in un diagramma delle precedenze.

Esercizio: disegnare il diagramma delle precedenze per il calcolo del prodotto di due matrici interi; tradurre con fork e join il diagramma delle precedenze trovato.

Esercizi

Esercizio: tradurre con fork e join i diagrammi delle precedenze mostrati accanto.

P1

P3 P2

P1

P4

P2 P3

P6

P4 P5

Fork & Join: Espressività

Queste due primitive sono sufficienti a tradurre un qualsiasi diagramma delle precedenzeVantaggi:

flessibilitàespressività

Svantaggi:basso livello di astrazionenon impongono alcuna particolare struttura al programma concorrente

Altri Costrutti per Esprimere Programmi Concorrenti

cobegin P1 || P2 || … || Pn coend

P1

Esegue n istruzioni concorrentementeNon sono sufficientemente espressive da esprimere qualsiasi diagramma delle precedenzeRisulteranno comode per esprimerne alcuni

P2 … Pn

Quando Eseguire Concorrentemente?

Dato un programma sequenziale, non è difficile costruire un equivalente diagramma delle precedenzeTuttavia è opportuno stabilire un criterio generale per capire se due istruzioni possono essere eseguite concorrentemente o meno:

per ottenere diagrammi delle precedenze che esprimono il massimo grado di parallelismo possibileper automatizzare il calcolo dei vincoli che esprimono

Quando è lecito eseguire concorrentemente due istruzioni ia e ib ?

Dominio e Rango

Indichiamo con A, B, … X, Y, … un’area di memoriaUna istruzione i

dipende da una o più aree di memoria che denotiamo domain(i), ovvero dominio di ialtera il contenuto di una o più aree di memoria che denotiamo range(i) di i, ovvero rango di i

Ad es. per la procedura Pprocedure PbeginX ← A + X;Y ← A * B;

end

domain(P) = {A, B, X}

range(P) = {X, Y}

Condizioni di Bernstein

Quando è lecito eseguire concorrentemente due istruzioni ia e ib ?

se valgono le seguenti condizioni, dette Condizioni di Bernstein:

1. range(ia) ∩ range(ib) = Ø

2. range(ia) ∩ domain(ib) = Ø

3. domain(ia) ∩ range(ib) = Ø

Condizioni di Bernstein (2)

Si osservi che non si impone alcuna condizione sudomain(ia) ∩ domain(ib)

Sono banalmente estendibili al caso di tre o più istruzioni

Esempi di violazione per le due istruzioni:X ← Y + 1; X ← Y – 1; (violano la 1.)X ← Y + 1; Y ← X - 1 ; (violano la 2. e la 3.)scrivi X; X ← X + Y; (violano la 3.)

Effetti delle Violazioni

Quando un insieme di istruzioni soddisfa le condizioni di Bernstein, il loro esito complessivo sarà sempre lo stesso indipendentemente dall’ordine e dalle velocità relative con cui vengono eseguite

in altre parole, indipendentemente dalla particolare sequenza di esecuzione seguita dai processoriovvero, sarà sempre equivalente ad una loro esecuzione seriale

Al contrario, in caso di violazione, gli errori dipendono dall’ordine e dalle velocità relative generando il fenomeno dell’interferenza

Esempio di Interferenza (1)

La disponibilità di un volo di una compagnia aerea è memorizzata in POSTI=1. Due signori nel medesimo istante ma da due postazioni distinte, chiedono rispettivamente di prenotare l’ultimo posto e di disdire la prenotazione già effettuataLe due richieste vengono tradotte in queste sequenze di istruzioni elementari indivisibili:

procedure Prenotabegin

Ra← POSTI - 1;POSTI ← Ra ;

end

procedure Disdicibegin

Rb← POSTI + 1;POSTI ← Rb ;

end

Esempio di Interferenza (2)

L’esecuzione concorrente da luogo ad una qualsiasi delle possibili sequenze di interleaving. Consideriamo un campione di tre sequenze:

Ra← POSTI - 1;Rb ← POSTI + 1;POSTI ← Rb ;POSTI ← Ra ;

(POSTI=0)

Ra← POSTI - 1;POSTI ← Ra ;Rb← POSTI + 1;POSTI ← Rb ;

(POSTI=1)

Rb← POSTI + 1;Ra ← POSTI - 1;POSTI ← Ra ;POSTI ← Rb ;

(POSTI=2)

esecuzione sequenziale

Interferenza

Si ha interferenza in presenza didue o più flussi di esecuzionealmeno un flusso di esecuzione eseguente scritture

Perchéun flusso esegue un cambio di stato dell’area di memoria in maniera non atomicagli stati transienti che intercorrono tra quello iniziale a quello finale sono visibili a flussi di esecuzione diversi da quello che li sta producendo

Origine dei Fenomeni di Interferenza

stato consistente

iniziale

stato consistente

finale

flusso di esecuzione

stato transiente

stato transiente

stato transiente

flusso di esecuzione scrittore

Errori Dipendenti dal Tempo

L’interferenza causa errori particolarmente temibili perché dipendenti dalla sequenza di interleaving effettivamente eseguita

Questi errori sono particolarmente temibili perché

ciascuna sequenza di esecuzione può produrre effetti diversila scelta della particolare sequenza adottata è (dal punto di vista del programmatore) casuale

Caratteristiche degli Errori Dipendenti dal Tempo

irriproducibili: possono verificarsi con alcune sequenze e non con altre

indeterminati: esito ed effetti dipendono dalla sequenza

latenti: possono presentarsi solo con sequenze rare

difficili da verificare, e testare: perché le tecniche di verifica e testing si basano sulla riproducibilità del comportamento

Il Programmatore e gli Errori Dipendenti dal Tempo

Il programmatore non può fare alcuna assunzione:sulla particolare sequenza di interleaving eseguita, ovverosulle velocità relative dei vari processori virtualisu un qualsiasi altro tipo di sincronismo legato alla specifica implementazione dei processori virtuali

Un programma che implicitamente od esplicitamente basa la propria correttezza su ipotesi circa la velocità relativa dei vari processori, è scorrettoEsiste una sola assunzione che possono fare i programmatori sulla velocità dei processori virtuali…

Assunzione di Progresso Finito

Tutti i processori virtuali hanno una velocità finita non nulla

Questa assunzione è l’unica che si può fare sui processori virtuali e sulle loro velocità relative

Starvation & Deadlock

Esistono due diverse situazioni che possono invalidare l’assunzione di progresso finito

starvation: quando un processo rimane in attesa di un evento che pure si verifica infinite volte

un sistema di processi che garantisce contro questa evenienza si dice che gode della proprietà di fainess

deadlock (o stallo): quando due o più processi rimangono in attesa di eventi che non potranno mai verificarsi a causa di condizioni cicliche nel possesso e nella richiesta di risorse

esempio classico: un processo Pa possiede una risorsa R1 e richiede una risorsa R2 già posseduta da un altro processo Pb; quest’ultimo a sua volta richiede l’uso di R1

Interazione tra Processi Concorrenti

Due processi possono essere:disgiuntiinteragenti

competizione: due o più processi chiedono l’uso di una risorsa comune riusabile e di molteplicità finitacooperazione: due o più processi cooperano per raggiungere un obiettivo comune

Competizione

La competizione occorre ogni qualvolta che c’è una risorsa riusabile condivisa e di molteplicità finita (spesso seriale)

incrocio stradalesportellista alle postestampante dipartimentalerete ethernet

In presenza di competizione è necessario “gestire” i possibili fenomeni di interferenza

Caratteristiche Rilevanti dell’Esecutore

Quale strategia risulta più opportuna per gestire l’interferenza dipende largamente

dalla tollerabilità degli effettidalla rilevabilità dei fenomeni di interferenzadalla recuperabilità degli effetti eventualmente cancellando, ripetendo e disfacendo alcune operazioni

Ad esempio i DBMS moderni possiedono interi sotto-sistemi unicamente dedicati alla gestione della concorrenza con diverse politiche

Strategie per Gestire l’Interferenza

Conseguenzeinaccettabili

ad es. incrocio stradaletrascurabili

applicazioni non criticherilevabili e controllabili

ad es. iteratoririlevabili e recuperabili

ad es. rete ethernet

Strategieevitare qls interferenza

conservatriciignorare

rilevare ed evitarefail-fast

rilevare e ripetereottimistiche

...

Metodi per la Gestione dell’Interferenza

immutabilità delle aree di memoriaconfinamento degli aggiornamenti

per flusso di esecuzioneper aree di memoria …

esclusione delle sequenze di interleavingpolitiche basate sullo stato

ottimistiche; try-and-seeconservative; check-and-act

Programmazione Concorrente ed Architetture degli Elaboratori

Architetture più diffuseSMPdata-flow, per il calcolo vettorialecluster

Scenario più comune: processi sequenziali debolmente connessi