• Non ci sono risultati.

Parte 2: Thread

N/A
N/A
Protected

Academic year: 2021

Condividi "Parte 2: Thread"

Copied!
7
0
0

Testo completo

(1)

1

5 Thread

• Ad un generico processo, sono associati, in maniera univoca, i seguenti dati e le seguenti informazioni:

– codice del programma in esecuzione

– un’area di memoria contenente le strutture dati dichiarate nel programma in esecuzione

– file aperti

– stack (per le chiamate di procedure e funzioni) – contenuto dei registri della CPU

2

5 Thread

• Consideriamo due processi che devono lavorare sugli stessi dati. Come possono fare, se ogni processo lavora su un’area di memoria diversa?

– i dati possono essere scambiati mediante messaggi o memoria condivisa, ma questa soluzione è inefficiente perché richiede l’intervento del SO (vedremo queste cose in pratica nel corso di laboratorio)

– i dati possono essere tenuti in un file che viene acceduto a turno dai due processi. Ancora più inefficiente!

3

5 Thread

• Ad esempio, in un editor di testo:

– un processo gestisce l’input e i comandi di formattazione dell’utente

– un altro processo esegue il controllo automatico di errore

• I due processi dovrebbero lavorare sullo stesso testo • La copia corrente del testo è mantenuta in MP, ma

come fanno i due processi a condividere la stessa copia, se ogni processo ha un diverso spazio di indirizzamento?

(2)

• Un normale processo è contraddistinto da un unico

Thread (filo) di computazione

codice dati file

registri stack

thread

5

5 Thread

• Un processo Multi-Thread è fatto di più thread, detti peer thread. Un insieme dei peer thread è detto task.

6

5 Thread

• Ad ogni thread è associato in modo esclusivo il suo stato della computazione, fatto da:

– valore del program counter e degli altri registri della CPU – uno stack

• Ma un thread condivide con i suoi peer thread:

– il codice in esecuzione – i dati

(3)

7

5 Thread

• La differenza fondamentale tra un processo e un insieme di peer thread (o task), è quindi che:

– la vita di un processo si sviluppa lungo un unico percorso (o “filo”) di computazione, fatto della sequenza di istruzioni eseguite dal processo.

– la vita di un task è fatta di più thread, ognuno dei quali è contraddistinto dal proprio “filo” di computazione

8

5 Thread

• Se c’è una sola CPU, il context switch avviene anche tra ognuno dei thread di un task, in modo che tutti possano portare avanti la computazione • Ma il context switch fra peer thread richiede il

salvataggio e il ripristino solo dei registri della

CPU e dello stack (che sono diversi per ogni

thread)

• Codice, dati e file aperti sono gli stessi per tutti, e

non devono essere cambiati: IL CONTEXT SWITCH TRA PEER THREAD E’ MOLTO PIU’ VELOCE

9

5 Thread

• Il context switch tra processi è molto più oneroso per il SO del context switch tra peer thread, perché nel primo caso sono coinvolte più informazioni da cambiare.

• Per questa ragione, i normali processi sono spesso chiamati: heavy-weight process (HWP)

• Mentre per un singolo thread si usa spesso il termine: light-weight process (LWP)

(4)

11

5 Processi e Thread

(a) Tre HWP: ad ognuno corrisponde un unico thread (b) Un task (o processo) con tre LWP (threads)

12

5 Processi e Thread

(a) (b)

(a) Item condivisi da tutti i thread di un processo (b) Item privati di ciascun thread

(5)

13

5 Thread

• Ma come si fa a distinguere tra i thread di un task (in modo da far fare a ciascuno una cosa diversa), se questi condividono lo stesso codice?

• Con delle opportune funzioni di libreria (system call), che all’interno del codice permettono di creare i thread necessari, e specificano per ciascun thread quale pezzo di codice deve eseguire quel thread

14 int n, in, out;

type item = ...; item buffer [n];

void *produttore( ); // contiene il codice del thread produttore void *consumatore( ); // contiene il codice del thread consumatore main ( ) /* produttore e consumatore */

{ ...

pthread_create(produttore); // crea il thread produttore pthread_create(consumatore); // crea il thread consumatore }

void *produttore ( ) {

qui il codice del produttore }

void *consumatore ( ) {

qui il codice del consumatore }

ora le variabili sono automaticamente condivise

Il main specifica quanti thread ci sono nel task e associa ad ogni thread il suo codice il codice del produttore è lo stesso di prima il codice del consumatore è lo stesso di prima 15

5 Thread a livello utente

• In alcuni sistemi, il SO non “sa” dell’esistenza dei threads. Si dice che i thread esistono solo a livello utente.

• Il context switch da un thread all’altro (all’interno dello stesso task) avviene mediante opportune funzioni di libreria chiamate all’interno del codice dei thread stessi.

• Quando un thread sta per fermarsi, specifica prima quale peer thread deve proseguire la computazione

(6)

• Il SO vede un task fatto di più thread come un normale processo, e gli assegna la CPU secondo il criterio di scheduling adottato.

• All’interno del task, il tempo di CPU è suddiviso tra i vari peer thread a seconda del codice di cui sono fatti.

• Se un thread si blocca senza farne partire un altro, tutto il tempo di CPU assegnato a quel task (e quindi a tutti i peer thread) viene sprecato

17

5 Thread a livello utente

18

5 Thread a livello kernel

• Il SO deve mantere delle strutture dati per gestire sia i processi che i thread

• Quando un thread si blocca, o termina il suo quanto di tempo, è il SO che assegna la CPU:

– a un altro thread dello stesso task – a un altro thread di un altro task – a un altro processo normale

(7)

19

5 Thread a livello kernel

20

5 Differenze tra kernel e user-level

thread

• La commutazione fra thread user-level non richiede l’intervento del SO ed è quindi più veloce

• La commutazione fra thread richiede il SO, ma un thread bloccato non blocca tutto il task • Molti SO supportano entrambi i tipi di thread

21

5 Vantaggi nell’uso dei thread

• Efficienza: in Solaris, creare un LWP richiede circa 30 volte meno tempo che creare un HWP. Il context switch tra peer thread richiede 5 volte meno tempo del context switch tra processi

• Condivisione di dati e risorse: più thread possono lavorare sugli stessi dati senza intervento del SO • Uso di architetture con più CPU: i thread sono naturalmente adatti per lavorare su più CPU in parallelo che condividono la stessa MP

Riferimenti

Documenti correlati

• Il metodo run della classe di libreria Thread definisce l’insieme di statement Java che ogni thread (oggetto della classe) eseguirà.. concorrentemente con gli

Il programma in C riportato in seguito usa funzioni di libreria definite nello standard POSIX (supportato da quasi tutti i sistemi UNIX) per creare più thread e mandarli in

•  Per attivare il thread deve essere chiamato il metodo start() che invoca il metodo run() (il metodo run() non può essere. chiamato direttamente, ma solo

implementazione del concetto di monitor: un oggetto java è associato ad un mutex ricorsivo tramite il quale è possibile disciplinare gli accessi da parte di diversi thread allo

 La funzione DEVE ESSERE CHIAMATA su una variabile mutex che sia già bloccata e di proprietà del thread chiamante. In tal caso la funzione pthread_mutex_unlock sblocca la

▪ Assegnare memoria e risorse per la creazione di nuovi processi è oneroso; poiché i thread condividono le risorse del processo cui appartengono, è molto più con- veniente creare

 Wait (and act) for a single thread within a large group of

Dato che le operazioni realizzate in pipeline hanno latenza diversa tra loro e maggiore delle aritmetiche corte, più operazioni aritmetiche possono essere in