Processi
Processi
Processi
dei Processi
Programma: Descrizione di un algoritmo utilizzando un linguaggio di
programmazione. Un insieme di byte che contiene le istruzioni che
dovranno essere eseguite (Entità Passiva)
zombie
init ready running
sleeping
swapped terminated
Stati di un processo pesante (Caso Generale)
- init: caricamento in memoria del processo e inizializzazione delle strutture
dati del Sistema Operativo
- ready: processo pronto ad utilizzare la CPU
- running: processo in esecuzione (utilizza la CPU)
- sleeping: processo sospeso in attesa di un evento
- terminated: deallocazione del processo dalla memoria
thread
Vantaggi dei thread
• UNIX: più processi utente ciascuno con un solo thread (processi pesanti)
• Supporto della Java VM: un solo processo, più thread (green thread) ma
può utilizzare le API del sistema operativo ospitante (native thread)
• Linux, Windows, Mac OSx, Solaris: più processi utente ciascuno con più
thread
Realizzazione dei thread a livello kernel del sistema operativo (native thread)
Tipi di interazione:
• Viene assegnato a x un valore non definito e l’ultimo valore valido contenuto nella
pila viene cancellato dal nuovo valore di y.
Istruzioni Indivisibili
• Data un'istruzione I(d), che opera su un dato d, essa è indivisibile (o atomica) , se,
durante la sua esecuzione da parte di un processo P, il dato d non è accessibile ad
altri processi.
• I(d), a partire da un valore iniziale d0 , può operare delle trasformazioni sullo stato
di d, fino a giungere allo stato finale dF; poiché I(d) è indivisibile, gli stati
intermedi non possono essere rilevati da altri processi concorrenti.
Sezione Critica
• Quando un processo si trova all’esterno di una sezione critica non può rendere
impossibile l’accesso alla stessa sezione ad altri processi.
Il problema del deadlock
Quando due o più processi competono per l’uso di risorse comuni, è possibile
incorrere in situazioni di stallo (deadlock, o blocco critico)
Esempio di Deadlock
Si considerino due processi P1 e P2 che condividono le stesse risorse R1 e R2, da
accedere in mutua esclusione; se contemporaneamente:
• P1 sta usando R1 e richiede R2
• P2 sta usando R2 e richiede R1
P1 e P2 sono bloccati indefinitamente: deadlock!
Domande Proposte:
public void run(){ // Definizione delle azioni del Thread nel metodo run()
…………………………………………………………………
}
ESEMPIO di creazione di un Thread Java implementando l’interfaccia Runnable
public class EsempioRunnable extends MiaClasse implements Runnable { // implementazione dell’interfaccia
public void run() { //Implementazione del metodo run() che conterrà le azioni svolte dal Thread
………………………………………………………………………………
}
}
- Se il thread sospeso aveva acquisito una risorsa in maniera esclusiva (ad es., interrotto
durante l’esecuzione di un metodo synchronized), tale risorsa rimane bloccata
(DEPRECATO)
- ATTENZIONE: Alcuni dei metodi proposti possono generare delle eccezioni ed è quindi
necessario inserirli all’interno di una sezione try, catch e finally.
Ciclo di vita di un Thread Java yield()
Dead
• New Thread:
- subito dopo l’istruzione new()
- il costruttore alloca e inizializza le variabili di istanza
• Not Runnable: - Il thread non può essere messo in esecuzione. Entra in questo stato quando è
in attesa della terminazione di un’operazione di I/O, cerca di accedere ad un metodo
“synchronized” di un oggetto bloccato, o dopo aver invocato uno dei seguenti metodi: sleep(),
wait(), suspend(). Esce da questo stato quando si verifica la condizione complementare
• Dead: - Il thread giunge a questo stato per “morte naturale” (termine metodo run() ) o perché
un altro thread ha invocato il suo metodo stop() [deprecato]
Per evitare che thread diversi interferiscano durante l’accesso ad oggetti condivisi si
possono imporre accessi esclusivi:
• La JVM supporta la definizione di lock sui singoli oggetti tramite la keyword synchronized
• Un thread che non riesce ad entrare in una sezione synchronized resta sospeso sulla
richiesta della risorsa fino a che la risorsa non diventa disponibile
Metodo wait() della classe Object
• il thread che la invoca si blocca in attesa che un altro thread invochi notify() o notifyAll()
per quell’oggetto.
• Ogni volta che un metodo attua una variazione dello stato di un oggetto, esso deve
invocare notifyAll()