• Non ci sono risultati.

Informatica 3. Informatica 3. LEZIONE 6: Il controllo dell esecuzione. Lezione 6 - Modulo 1. Errori durante l esecuzione. Il controllo dell esecuzione

N/A
N/A
Protected

Academic year: 2022

Condividi "Informatica 3. Informatica 3. LEZIONE 6: Il controllo dell esecuzione. Lezione 6 - Modulo 1. Errori durante l esecuzione. Il controllo dell esecuzione"

Copied!
7
0
0

Testo completo

(1)

Politecnico di Milano - Prof. Sara Comai 1

LEZIONE 6: Il controllo dell’esecuzione

• Modulo 1: La gestione delle eccezioni

• Modulo 2: Programmazione concorrente

Informatica 3

Politecnico di Milano - Prof. Sara Comai 2

Lezione 6 - Modulo 1

La gestione delle eccezioni

Informatica 3

Il controllo dell’esecuzione

• Il controllo dell’esecuzione può avvenire tramite:

– Strutture di controllo a livello di istruzioni

• Esecuzione condizionale: If-then-else, Case

• Iterazione: While, For, Repeat

– Strutture di controllo a livello di unità di esecuzione (procedura, modulo)

• Chiamata a funzione e ritorno

• Gestione delle eccezioni

• Altre strutture di controllo utilizzate nella programmazione concorrente

Errori durante l’esecuzione

• Durante l’esecuzione di un programma si possono verificare delle condizioni per cui il programma è errato

– Indice dell’array che eccede i limiti – Divisione per zero

– Radice quadrata di un numero negativo

– Quantità di memoria da allocare per il programma non disponibile

• Utilizzo di strutture di controllo convenzionali:

– Ogni volta che si accede all’array occorre testare il valore dell’indice

– Ogni volta che si esegue una divisione occorre verificare se il divisore è 0

– …

(2)

Politecnico di Milano - Prof. Sara Comai 5

Eccezioni

• Gestione delle eccezioni:

– Eccezione: comportamento anomalo non desiderato che accade raramente

– I linguaggi di programmazione moderni permettono di gestire le eccezioni

• Definizione di un’eccezione

• Definizione dell’azione da intraprendere (exception handler)

– La gestione delle anomalie può essere spostata al di fuori del flusso principale del programma

Politecnico di Milano - Prof. Sara Comai 6

Definizione delle eccezioni

Trattamento delle eccezioni nei linguaggi di programmazione:

– Quali sono le eccezioni da trattare?

– Quali unità del programma possono generare un’eccezione e come?

– Come e dove definire un exception handler?

– Come si passa il controllo dall’eccezione al suo exception handler?

– Come prosegue l’esecuzione una volta che l’eccezione è stata gestita?

Gestione delle eccezioni in C++

• Le eccezioni possono essere generate – Dall’ambiente di esecuzione (es. divisione per

zero)

– Esplicitamente dal programma: try, catch e throw

• Il codice da controllare deve essere contenuto in un blocco try

• Se all’interno di un blocco try si verifica un’eccezione, questa viene lanciata tramite l’istruzione throw:

trasferisce un oggetto al gestore dell’eccezion

• L’eccezione viene raccolta da una catch ed elaborata

Esempio

Divisione tra due interi:

void dividi (int a, int b){

try { //blocco try if (!b) throw b; //eccezione

cout << “Risultato della divisione: ” << a/b << endl;

}

catch (int i) { //azione da intraprendere

cout << “è stata effettuata una divisione per zero” << endl;

} }

(3)

Politecnico di Milano - Prof. Sara Comai 9

Il controllo del programma

• Una volta eseguita la catch il controllo del programma passa all’istruzione successiva alla try

– Non funzione come una chiamata di funzione!

void dividi (int a, int b){

try { //blocco try if (!b) throw b; //eccezione

cout << “Risultato della divisione: ” << a/b << endl;

}

catch (int i) { //azione da intraprendere

cout << “è stata effettuata una divisione per zero” << endl;

} }

– Se l’errore non può essere corretto all’interno della catch si fa terminare il programma (exit(), abort())

Politecnico di Milano - Prof. Sara Comai 10

Try e catch

• Ad un blocco try possono essere associate più catch, ognuna per un tipo diverso

– Viene eseguita la catch del tipo specificato

try { // blocco try

... throw 1;

... throw ‘c’;

}

catch (int i) { ... } // catch per tipo intero catch (char c) { ... } // catch per tipo carattere

– Se si lancia un’eccezione per la quale non

esistono catch il programma termina in modo anormale

Raccolta di tutte le eccezioni

• Per raccogliere tutte le eccezioni e non solo quelle di un determinato tipo:

catch(…) { //lista di argomenti di lungh. variabile //elaborazione delle eccezioni

}

• Esempio:

try{

if (!b) throw b; //lancia un intero if (b==1) throw ‘a’; //lancia un carattere;

if (b==2) throw 12.12; //lancia un double;

}

catch(int i) { cout << “Eccezione intera” << endl; } catch(…) { cout << “Eccezione non intera” << endl; }

Restrizione del tipo di eccezioni

• Per le funzioni richiamate all’interno di un blocco try è possibile restringere il tipo di eccezioni che la funzione può lanciare – Se si cerca di sollevare un’eccezione non presente nell’interfaccia

viene richiamata automaticamente la funzione unexpected(): il suo comportamento di default (ridefinibile) chiama abort();

try { funzione();

}

catch{ //blocco catch }

void funzione (void) throw (int, char) { //corpo funzione

throw () se si desidera che la funzione non lanci eccezioni Se non c’è nulla può lanciare qualsiasi eccezione

(4)

Politecnico di Milano - Prof. Sara Comai 13

Rilancio di un’eccezione

• All’interno del gestore dell’eccezione (catch) si possono rilanciare eccezioni, richiamando throw senza specificare nè l’errore nè il tipo

– L’eccezione corrente viene passata a una sequenza try- catch più esterna

void funzione(int b){

try { if (!b) throw b;

//…

}

catch (int i) { //…

throw; //rilancia l’eccezione passando l’intero }

} void main (){

int a=0;

//…

try { funzione(a);

//…

}

catch (int i) { //…

} }

Politecnico di Milano - Prof. Sara Comai 14

Conclusioni

• Quali sono le eccezioni da trattare?

– In quasi tutti i linguaggi: eccezioni built-in ed eccezioni definite dal programmatore

• Quali unità del programma possono generare un’eccezione e come?

– In C++ (e Ada) le eccezioni possono essere associate a qualsiasi blocco. In altri linguaggi solamente a routine (es. Eiffel).

– In C++ l’eccezione viene lanciata con l’istruzione throw

• Come e dove definire un exception handler?

– In C++ viene definito tramite l’istruzione catch, dopo il blocco try

• Come si passa il controllo dall’eccezione al suo exception handler?

– In C++ (e Ada) viene passato all’handler appropriato tramite propoagazione.

• Come prosegue l’esecuzione una volta che l’eccezione è stata gestita?

– In C++ (e Ada) ripresa dall’istruzione successiva al blocco interrotto – Ripresa dell’esecuzione (PL/1): da dove il programma è stato interrotto

Lezione 6 - Modulo 2

Programmazione concorrente

Informatica 3 Programmazione concorrente

• I linguaggi per la programmazione concorrente permettono di strutturare il software in unità concorrenti da eseguire in parallelo

– Sistemi multiprocessori

– Sistemi distribuiti con computer che cooperano – Sistemi monoprocessori

• Le unità concorrenti prendono il nome di processi

• Thread: processi che condividono un singolo spazio

di indirizzamento (accesso allo stesso ambiente globale)

Parallelismo fisico Parallelismo logico

(5)

Politecnico di Milano - Prof. Sara Comai 17

Problema dei 5 filosofi

• Problema posto da Edsger Dijkstra nel 1971

• Illustra gli aspetti di base del multi- threading

Problema:

– 5 filosofi seduti intorno ad un tavolo – ognuno ha di fronte un piatto di

spaghetti e tra un piatto e l’altro si trova una forchetta

– nella vita i filosofi alternano periodi in cui pensano a periodi in cui mangiano – per mangiare gli spaghetti hanno

bisogno di 2 forchette

Politecnico di Milano - Prof. Sara Comai 18

Problema dei 5 filosofi (2)

– Quando il filosofo vuole mangiare deve acquisire 2 forchette, una alla volta

• se riesce ad acquisirle mangia per un po’ e poi le rimette al loro posto e ricomincia a pensare

– Si tratta di un problema di allocazione delle risorse:

dobbiamo assegnare risorse ai processi (forchette ai filosofi) necessarie per compiere il loro lavoro – Problema generalizzato: un insieme finito di thread

condivide un insieme finito di risorse e ogni risorsa può essere usata solamente da un thread alla volta

Sincronizzazione

– Il problema fondamentale è sincronizzare l’accesso dei filosofi alle forchette

– Soluzione più semplice: i filosofi (thread) sincronizzano l’accesso alle forchette (risorse) usando memoria condivisa

• per acquisire una forchetta un filosofo deve testare un flag condiviso che dice se la forchetta è già in uso o meno

• il filosofo procede se il flag indica che la forchetta non è in uso

• dopo aver acquisito la forchetta il filosofo modifica il valore del flag – Problema di questa soluzione:

• tra l’istante in cui un filosofo testa il valore del flag e l’istante in cui ne modifica il valore per indicare che la forchetta non è disponibile altri filosofi potrebbero procedere ad acquisire la forchetta --> problema di “race condition” (corsa critica)

• occorre un metodo per proteggere i flag condivisi, in modo tale che gli accessi al flag siano mutuamente esclusivi

Mutua esclusione

– Flag mutuamente esclusivo: può essere acceduto in un determinato momento solamente da un thread, che è l’unico che può modificarne il valore

– Uno dei metodi per ottenere mutua esclusione:

• controllare l’accesso alle risorse condivise tramite semafori

• La soluzione tramite semafori risolve il problema della mutua esclusione e anche dell’attesa dei filosofi quando le forchette non sono disponibili

(6)

Politecnico di Milano - Prof. Sara Comai 21

Semafori

• Dijkstra, 1965: semaforo come meccanismo per sincronizzare thread concorrenti

• Due operazioni primitive:

– P (dall’olandese proberen = testare): testa lo stato del semaforo e restituisce il controllo al thread se la risorsa è disponibile, altrimenti mantiene il thread in attesa

– V (dall’olandese verhogen = incrementare): rilascia la risorsa controllata dal semaforo; la risorsa diventa disponibile ad altri thread

– Esistono diversi tipi di semafori:

• Semafori basati su conteggio: esiste un pool di risorse ed il semaforo tiene il conto di quante risorse sono disponibili

• Semafori binari: vi può accedere un thread alla volta

• Semafori mutex: semafori binari che permettono di gestire problemi di mutua esclusione

Politecnico di Milano - Prof. Sara Comai 22

Implementazione

long WINAPI philosopher(long n) { /* thread che rappresenta un filosofo */

for (;;) { think(n);

WaitForSingleObject(fork[(n + 1) % N], INFINITE);

Sleep(0);

WaitForSingleObject(fork[n], INFINITE);

eat(n);

ReleaseMutex(fork[(n + 1) % N]);

ReleaseMutex(fork[n]);

} }

P sulla forchetta di destra P sulla forchetta di sinistra V sulle due forchette

Blocco critico

– Problema della soluzione basata su semafori:

• può accadere che tutti i filosofi abbiano una sola forchetta - rimangono tutti in attesa della seconda forchetta

--> problema del blocco critico (deadlock)

– Possibile soluzione:

• il filosofo prende la forchetta di sinistra, testa se la forchetta di destra è disponibile o meno

• se non è disponibile entro un certo periodo di tempo rilascia la forchetta di sinistra

• attende per un certo periodo di tempo (casuale) e poi riprova

Blocco individuale

– Altro problema: blocco individuale (starvation)

• può accadere che un filosofo non riesca mai ad accedere alle forchette

• il tempo di attesa è non-deterministico: non si può sapere in anticipo quant’è il tempo massimo di attesa per una risorsa

• Soluzione: adottare politiche di allocazione globali – ad es. politiche di priorità che dipendono dal tempo di

attesa

(7)

Politecnico di Milano - Prof. Sara Comai 25

Conclusioni

• La programmazione multi-thread è molto più difficile della programmazione sequenziale

• Richiede di conoscere i meccanismi di

sincronizzazione e comunicazione tra thread, come i diversi tipi di semafori, monitor, sezioni critiche, segnali, messaggi, code, mailbox, ecc.

• I linguaggi di programmazione che supportano in modo nativo la programmazione concorrente forniscono le primitive per gestire la creazione di processi e la loro sincronizzazione

• In altri linguaggi è possibile simularla

Riferimenti

Documenti correlati

Dunque la coscienza è un prodotto del cervello, il quale opera secondo le leggi della

I dati acquisiti tramite Archeo, sia visuali sia testuali, vengono infine scaricati nel sistema fisso e automaticamente inseriti nella base di oggetti re- lativa al sito che,

GeoARQUEOS is a programme designed with Avenue and Crystal Reports for the purpose of keeping the digital cartography of the Andalusian Archaeological Heritage updated. Its three

Finally, some genetic syndromes, such as Marfan and Ehler–Danlos syndrome, or more rare genetic diseases such as Hajdu-Cheney, Torg-Winchester and Shwachman-Diamond syndromes,

From the present study it emerges that, although expenses related to antiviral therapies increased by 34% per person-year, from 1997 to 2002 inpatient costs for HIV-positive

privatizzazione dei servizi di pubblica utilità e, di conseguenza, più rilevante è stato lo sforzo di regolazione pubblica degli stessi, ha mostrato ciò che la teoria aveva già

The choice of conformal coordinates for the spatial metric allows us to represent a Riemann surface on a complex plane with branch points (four branch points for a torus,.. 2g + 2

At the be- ginning, the rotating link has to pull the whole mass of chain plus the dumbbell, and therefore the dumbbells fall together.. But as the torsion sums up and the mass of