Sistemi Operativi (M-Z) - Processi, Thread & Communicazione fra Processi - Dipartimento di Matematica e ...
←
→
Trascrizione del contenuto della pagina
Se il tuo browser non visualizza correttamente la pagina, ti preghiamo di leggere il contenuto della pagina quaggiù
Sistemi Operativi (M-Z)
Processi, Thread &
Communicazione fra Processi
C.d.L. in Informatica
(laurea triennale)
A.A. 2019-2020
Prof. Mario F. Pavone
Dipartimento di Matematica e Informatica
Università degli Studi di Catania
mario.pavone@unict.it
mpavone@dmi.unict.itProcesso
l Definizione: una istanza di esecuzione di un programma.
l Si associano ad esso:
n spazio degli indirizzi:
n codice eseguibile;
n dati;
n stack;
n copia dei registri della CPU;
n file aperti;
n allarmi pendenti;
n processi imparentati.
l Tabella dei processi con un Process Control Block (PCB)
per ogni processo.Programma vs. Processo
l Programma: entità passiva -> contiene la lista delle istruzioni
memorizzate sul disco
l Processo: entità attiva
l Due processi associati allo stesso programma sono considerati
distinti
l uguale codice ma differenti dati; stack; etc.
l Share Code: solo una copia si trova in memoriaStato di un processo l 3 stati principali (+ 2 addizionali); l transizioni.
Creazione e terminazione
dei processi
l Creazione di un processo:
n in fase di inizializzazione del sistema;
n da parte di un altro processo (padre) o per un'azione dell'utente;
n metodologie:
n sdoppiamento del padre: fork e exec (UNIX);
n nuovo processo per nuovo programma: CreateProcess
(Win32).
l Terminazione:
n uscita normale (volontario): exit (UNIX), ExitProcess (Win32);
n uscita su errore (volontario);
n errore critico (involontario): alcuni sono gestibili, altri no;
n terminato da un altro processo (involontario): kill (UNIX),
TerminateProcess (Win32).Gerarchia dei Processi
l Un processo può crearne un’altro
l processo padre e processo figlio
l processo figlio può a sua volta crearne altri
l UNIX: process group
l processo speciale init
l In Windows: NO
l Tutti i processi sono uguali
l handle: token per il processo padreTabella dei processi
l SO mantiene una Tabella dei processi;
l Process Control Block (PCB);
l Scheduler (bottom fig.);
l Gestione degli interrupt per il passaggio di processo
(vettore di interrupt & procedura di servizio dell’interrupt):
n salvataggio nello stack del PC e del PSW nello stack attuale;
n caricamento dal vettore degli interrupt l'indirizzo della procedura
associata;
n salvataggio registri e impostazione di un nuovo stack;
n esecuzione procedura di servizio per l'interrupt;
n interrogazione dello scheduler per sapere con quale processo
proseguire;
n ripristino dal PCB dello stato di tale processo (registri, mappa
memoria);
n ripresa nel processo corrente.Code e accodamento
l Coda dei processi pronti e code dei dispositivi;
n strutture collegate sui PCB;
l Diagramma di accodamento:Thread
l Modello dei processi: entità indipendenti che raggruppano
risorse e con un flusso di esecuzione;
l può essere utile far condividere a più flussi di esecuzione lo
stesso spazio di indirizzi: thread;
l quando può essere utile?
n esempi: web-browser, videoscrittura, web-server, …Thread: an example
WORD PROCESSOR
Un thread si occupa di interagire con l’utente; un altro
formatta il documento; un terzo fa il backup su HDThread: an example
WEB SERVER PROCESS
NOTA: il dispatcher è un ciclo infinito che acquisisce richieste di
lavoro e le passa ad un worker threadThread 3 processi 3 thread
Thread
l Un thread è caratterizzato da:
n PC, registri, stack, stato;
n condivide tutto il resto;
n no protezione di memoria.
l scheduling dei thread;
l cambio di contesto più veloce;
Sistemi MultithreadingThread
l Thread diversi nello stesso processo non sono indipendenti
l Condivisione e No protezione di memoria
l un thread può leggere, scrivere o cancellare lo stack di un altro thread
l Stesso user -> Cooperano -> non entrano in conflitto
l Thread apre file => è visibile ad ogni thread nel processo
l Unità gestione delle risorse => ProcessoThread
l Ogni Thread ha un proprio Stack: perchè?
l Utilizzano procedure diverse
l storia di esecuzione diversaStati di un Thread l Anche un thread può trovarsi in uno dei seguenti stati l Transizioni di stato => analogo a quello dei processi.
Operazioni sui Thread
l Nei sistemi Multithreading i processi inizano con un singolo thread
l operazioni tipiche sui thread:
n thread_create: un thread ne crea un altro;
n thread_exit: il thread chiamante termina;
n thread_join: un thread si sincronizza con la fine di un altro thread;
n thread_yield: il thread chiamante rilascia volontariamente la CPU
n no clock interruptProgrammazione multicore
l I thread permettono una migliore scalabilità con core con
hypertreading e soprattutto con sistemi multicore;
l con un sistema single-core abbiamo una esecuzione interleaved;
singola T T T T T T T T T ...
CPU 1 2 3 4 1 2 3 4 1
tempo
l su un sistema multi-core abbiamo parallelismo puro.
core 0 T T T T ...
1 3 1 3
core 1 T T T T ...
2 4 2 4
tempoProgrammazione multicore
l Progettare programmi che sfruttino le moderne architetture
multicore non è banale;
l principi base:
n separazione dei task;
n trovare aree per attività separate e simultanee
n bilanciamento;
n assicurarsi che eseguano lo stesso lavoro di uguale valore
n suddivisione dei dati;
n dividere i dati per essere eseguiti su core separati
n dipendenze dei dati;
n esecuzione delle attività sia sincronizzata
n test e debuggingThread a livello utente
l Vantaggio: il kernel non ne è a conoscenza
l utile se non c'è supporto da parte del kernel ai thread;
l Sistema Run-Time: raccolta di procedure per thread
l Tabella dei Thread
l gestita dal sistema run-time
NOTA: le procedure che
salvano lo stato del thread
e lo scheduler sono localiThread a livello utente
l Pro:
n thread switching veloce
n il dispatching non richiede trap nel kernel;
n scheduling personalizzato;
l Contro:
n Implementazione chiamate bloccanti
n una chiamata genera un blocco?
n select, & page-fault
n possibilità di non rilascio della CPU
n clock sistema run-timeThread a livello kernel
l No sistema run-time
l no tabella dei thread nel processo
l unica tabella dei thread del kernel;
l Pro:
n un thread su chiamata bloccante
non intralcia gli altri;
l Contro:
n cambio di contesto più lento
(richiede trap);
n creazione e distruzione più costose
(numero di thread kernel tipicamente limitato,
possibile riciclo).Modello ibrido
l prende il meglio dei due
l prevede un certo numero di thread del kernel;
l ognuno di essi viene assegnato ad un certo numero di thread
utente (eventualmente uno);
l assegnazione decisa dal programmatore.I thread nei nostri sistemi operativi
l Quasi tutti i sistemi operativi supportano i thread a livello
kernel;
n Windows, Linux, Solaris, Mac OS X,...
l Supporto ai thread utente attraverso apposite librerie:
n green threads su Solaris;
n GNU portable thread su UNIX;
n fiber su Win32.
l Librerie di accesso ai thread (a prescindere dal modello):
n Pthreads di POSIX (Solaris, Linux, Mac OS X, anche Windows);
n una specifica da implementare sui vari sistemi;
n threads Win32;
n thread in Java;
n wrapper sulle API sottostanti.Comunicazione fra processi
l Spesso i processi hanno bisogno di cooperare
l collegamento I/O tra processi
l Comunicazione ben strutturata
l InterProcess Communication (IPC)
l Problematiche da considerare:
1) come scambiarsi i dati;
2) accavallamento delle operazioni su dati comuni;
3) coordinamento sequenziale tra le operazioni (o
sincronizzazione).
l Corse critiche (race conditions)
l processi che lavorano su risorse condivise: chi viene prescelto
per l’esecuzione?Race Conditions l Spool di Stampa: demone di stampa & directory di spool Evitare che più processi accedino a dati condivisi contemporaneamente
Regioni Critiche
l Mutua Esclusione: garantire che il processo B utilizzi le
risorse condivise solo dopo che il processo A termini il
suo completo utilizzo
l Regione/Sezione Critica: parte di programma in cui si
accede alla memoria condivisaSezioni critiche
l Astrazione del problema: sezioni critiche e sezioni non
critiche.
l Quattro condizioni per avere una buona soluzione:
1. mutua esclusione nell'accesso alle rispettive sezioni
critiche;
2. nessuna assunzione sulla velocità di esecuzione o sul
numero di CPU;
3. nessun processo fuori dalla propria sezione critica può
bloccare un altro processo;
4. nessun processo dovrebbe restare all'infinito in attesa
di entrare nella propria sezione critica.Sezioni critiche: an example
Come realizzare la mutua esclusione
1) Disabilitare gli interrupt.
2) Variabili di lock.
3) Alternanza stretta:
int N=2
int turn
function enter_region(int process)
while (turn != process) do
nothing
function leave_region(int process)
turn = 1 – process
n può essere facilmente generalizzato al caso N;
n fa busy waiting (si parla di spin lock);
n implica rigidi turni tra le parti (viola condizione 3).Soluzione di Peterson
int N=2
int turn
int interested[N]
function enter_region(int process)
other = 1 – process
interested[process] = true
turn = process
while (interested[other] = true and turn = process) do
nothing
function leave_region(int process)
interested[process] = false
l ancora busy waiting;
l può essere generalizzato al caso N;
l può avere problemi sui moderni multi-processori a causa del riordino degli
accessi alla memoria centrale.Istruzioni TSL e XCHG
l Molte architetture (soprattutto multi-processore) offrono
specifiche istruzioni:
n TSL (Test and Set Lock);
n uso: TSL registro, lock
n operazione atomica e blocca il bus di memoria;
enter_region: leave_region:
TSL REGISTER,LOCK MOVE LOCK,#0
CMP REGISTER,#0 RET
JNE enter_region
RET
n XCHG (eXCHanGe);
n disponibile in tutte le CPU Intel X86;
l ancora busy waiting.Sleep e wakeup
l Tutte le soluzioni viste fino ad ora fanno spin lock;
n problema dell'inversione di priorità.
l Soluzione: dare la possibilità al processo di bloccarsi in modo passivo
(rimozione dai processi pronti);
n primitive: sleep e wakeup.
l Problema del produttore-consumatore (buffer limitato – N):
n variabile condivisa count inizialmente posta a 0;
function producer() function consumer()
while (true) do while (true) do
item = produce_item() if (count = 0) sleep()
if (count = N) sleep() item = remove_item()
insert_item(item) count = count – 1
count = count + 1 if (count = N – 1)
if (count = 1) wakeup(producer)
wakeup(consumer) consume_item(item)
n questa soluzione non funziona bene: usiamo un bit di attesa wakeup.Puoi anche leggere