Sei sulla pagina 1di 7

I Compendi OpenSource

di Giacomo Marciani

Teoria, Formulario e Suggerimenti Pratici

Sistemi Operativi

Thread
usso indipendente di esecuzione
1
all'interno di un processo,

Un thread un

che viene schedulato ed eseguito come tale dal sistema operativo, costituendo perci l'unit elementare di lavoro dei moderni sistemi time-sharing con supporto multithread . I thread di uno stesso processo condividono lo stesso spazio loro terminazione.

2 di indirizzamento , ma vivono come ussi d'esecuzione indipendenti no alla


Pur condividendo la stessa memoria globale, ogni thread pu eventualmente disporre di dati specifici di thread, ovvero di una copia privata di alcuni dati . Lo stato di un thread descritto dai seguenti elementi:

tid: identicatore del thread. stack um: registri: propriet dello scheduling: maschera dei segnali: dati specifici del thread: variabile

errno :
4 un processo composto da un solo thread: vi
La programmazione

Un heavyweight process

dunque un unico usso di esecuzione sequenziale.

monothread5 sviluppa applicazioni basate su heavyweight process.

Un multithread process un processo composto da pi thread: vi sono dunque pi ussi di esecuzione concorrenti e indipendenti. La programmazione

multithread sviluppa applicazioni basate su multithread process.

Programmazione Multithread

La programmazione multithread ore

un meccanismo per l'utilizzo eciente di

sistemi multicore, aiutando a sfruttare

al meglio la concorrenza. I vantaggi della programmazione multithread possono identicarsi nei seguenti quattro fattori principali:

riduzione del tempo di risposta:

un programma pu continuare la pro-

pria esecuzione, anche se una parte di esso bloccata o sta eseguendo un'operazione particolarmente lunga.

oggi la maggior parte dei moderni sistemi time-sharing supportano la programmazione multithread. 2 quindi i cambiamenti fatti da un thread sono visibili agli altri thread del processo, e letture/scritture nella stessa memoria richiedono tecniche di sincronizzazione previste dalle librerie thread-safe. 3 Pthread, Win32 e Java permettono l'impiego dei dati specici dei thread. 4 ovvero processo pesante, anche detto processo a singolo thread, o anche processo tradizionale. 5 anche detta programmazione tradizionale.
2

1 ad

migliore condivisione delle risorse :

a dierenza dei processi, che condi-

vidono le risorse tramite opportune tecniche IPC, i thread condividono per denizione la memoria e le risorse del processo al quale appartengono, denendo cos una comunicazione immediata.

maggiore ecienza:

il sistema operativo gestisce i thread pi rapidamente

di quanto non faccia con i processi .

maggiore scalabilit:

il multithreading sfrutta implicitamente il paral-

lelismo in sistemi multicore. In un sistema monocore la programmazione multithread realizza l'interfogliamento

dei thread.
multicore sono:

In un sistema multicore realizza invece il parallelismo dei

thread. Gli obiettivi principali della programmazione multithread in sistemi

separazione dei task : bilanciamento :

occorre esaminare a fondo le applicazioni al ne di

individuarvi porzioni di lavoro parallelizzabili. i vari task devono eseguire compiti di mole e valore conTalvolta pu

frontabili, cos da contribuire bilanciatamente al processo complessivo, di modo che risulti conveniente impegnare core distinti. multithread su pi core. risultare ininuente o addirittura sconveniente parallelizzare un'applicazione

suddivisione dei dati : dipendenze dei dati : test e debugging :

i dati devono essere suddivisi in modo da garantirvi

l'accesso e la manipolazione opportuna da parte di core distinti. la sincronizzazione dei thread deve garantire la co-

erenza dei dati condivisi. essendoci diversi possibili ussi di esecuzione, il test e il

debugging di applicazioni multithread intrinsecamente pi laborioso.

Modelli di programmazione multithread


I thread si distinguono in:

user thread7 : gestiti senza l'aiuto del kernel. kernel thread8 : gestiti interamente dal sistema operativo.

Le possibili corrispondenze stabilite fra user thread e kernel thread deniscono quattro modelli di programmazione multithread:

modello molti a uno: fa corrispondere pi user thread ad un singolo kernel thread. La gestione dei thread risulta eciente, in quanto, essendo svolta nello spazio utente, non necessario limitare il numero di

6 ad esempio, in Linux, creare un thread richiede un processo. 7 anche detti thread a livello utente. 8 anche detti thread a livello kernel.

1 10

del tempo richiesto per la creazione di

user thread. Tuttavia, poich il meccanismo di scheduling del kernel pu scegliere un solo kernel thread alla volta, talvolta impossibile realizzare una pura parallelizzazione .

modello uno a uno: fa corrispondere ciascun user thread ad un singolo


kernel thread. Ne risulta un maggiore grado di concorrenza, nonch la possibilit di sfruttare la parallelizzazione. Tuttavia questo modello limita il numero di thread gestibili dal sistema, in quanto ad ogni user thread deve necessariamente corrispondere un kernel thread, la cui creazione pu indurre un carico compromettente a livello prestazionale.

modello molti a molti: fa corrispondere pi user thread ad un numero minore uguale di kernel thread dei thread, e la possibilit della parallelizzazione.

10 . Ne risulta una gestione eciente

modello a due livelli: diusa variante del modello molti a molti,


che permette anche di vincolare uno user thread ad un singolo kernel thread.

Ptherads 11
procedurali

Una libreria dei thread una libreria necessaria ai linguaggi che fornisce al programmatore una API per la creazione e la gese

tione dei thread. Attualmente le librerie dei thread maggiormente in uso sono:

Pthreads, Win32

Java.

Pthreads una libreria dei thread


tate dalla libreria

nente tipi di dato e procedure C, esportate dall'header le

libpthread 12 .

standard POSIX (IEEE 1003.1c) contepthread.h e implemen-

Essa contiene pi di 60 funzioni, raggruppabili

in tre classi principali:

thread management: procedure per creare, distruggere, attendere un


thread.

mutex: costrutti e procedure di

mutua esclusione,

per garantire che un

solo thread possa eseguire ad un certo istante un blocco di codice.

condition variable:
di condizioni.

costrutti e procedure per la comunicazione tra

thread che condividono un mutex, per aspettare o segnalare il vericarsi

synchronization:

procedure che gestiscono l'accesso sincronizzato in

lettura e scrittura alla memoria condivisa dai thread.

di thread. 10 il numero di kernel thread pu dipendere dall'applicazione, o dall'architettura del calcolatore. 11 alcuni linguaggi di programmazione orientati agli oggetti includono una classe standard di tipo thread, i cui metodi realizzano tutte le funzionalit per la programmazione multithread. 12 spesso inclusa nella libreria libc.

9 se uno user thread invoca una chiamata di sistema bloccante, questa blocca l'intero insieme

Creazione di un thread
menti.

La routine

pthread_create crea e rende eseguibile

13 , e non pone 14 limiti impliciti al numero dei thread creabili all'interno di uno stesso processo .
Essa pu essere invocata sempre e ovunque nel codice Alla routine devono essere indicate le seguenti informazioni riguardanti il nuovo thread: il TID, gli attributi, la funzione da eseguire e i suoi eventuali argomenti. Una volta creato, un thread pu creare altri thread all'interno dello stesso processo: non vi un'implicita gerarchia o dipendenza tra i thread creati. In un programma multithread cambia la semantica della Se un thread invoca una

un nuovo thread, restituendo 0 in caso di successo o un numero d'errore altri-

fork() e della exec(). fork(), il nuovo processo pu contenere un duplicato di tutti i thread, oppure del solo thread invocante. Se un thread invoca una exec(),
il programma specicato sostituisce l'intero processo, inclusi tutti i thread.

Terminazione di un thread

Un thread pu terminare in diversi modi:

exec().

il processo a cui appartiene viene terminato con una

exit()

o con una

il thread termina l'esecuzione della sua routine. il thread viene cancellato da un altro thread tramite il thread chiama

pthread_cancel().

pthread_exit().
La cancellazione dei thread l'operazione Un I

Cancellazione di un thread

che permette di terminare un thread prima che completi il suo compito.

target thread15 un thread di cui sia stata richiesta la cancellazione.


pu essere cancellato senza problemi secondo due modalit:

punti di cancellazione sono punti della esecuzione in cui un target thread

16 . La cancellazione dei thread pu avvenire

cancellazione asincrona: terminazione

immediata del target thread.

cancellazione differita: il target thread termina in corrispondenza di


un

punto di cancellazione.

il thread bersaglio controlla periodicamente se

deve terminare, di modo che possa farlo opportunamente. Questo metodo permette di denire i cosiddetti cancellation point

17 , ovvero punti del 18 usso d'esecuzione in cui il thread sia cancellabile senza problemi .

una volta creato, un thread pu creare un altro thread invocando la routine pthread_create. 14 il numero massimo di thread creabili per ogni processo dipende dall'architettura dell hardware. 15 ovvero thread bersaglio. 16 come ad esempio l'incoerenza di dati condivisi. 17 ovvero punti di cancellazione. 18 il thread potrebbe non essere opportunamente cancellabile qualora venisse cancellato mentre aggiorna dati condivisi con altri thread, o nel caso in cui le sue risorse siano assegnate ad altri thread.

13 quindi,

Attesa di un thread
Un thread pool

La routine

pthread_join()

fa attendere al thread

chiamante la terminazione del thread specicato, restituendo 0 in caso di successo o un numero d'errore altrimenti. Non esiste alcun modo per attendere la terminazione di un thread qualunque. creazione del processo.

19 un insieme nito di thread in attesa creato alla


Il numero dei thread viene determinato da secondo schemi d'uso.

architetturali

determinato dinamicamente

euristiche
I compiti

assegnati al thread pool vengono indirizzati al primo thread disponibile, il quale, una volta terminato il lavoro, torner nello stato di attesa. Questo paradigma organizzativo elimina l'attesa dovuta alla creazione di nuovi thread e, limitando il numero di thread, garantisce ecienza prestazionale a quei sistemi che non sopporterebbero un elevato numero di thread concorrenti.

Gestione dei segnali



causa del segnale.

Un segnale pu essere:

segnale sincrono: inviato al processo/thread che ha eseguito l'operazione

segnale asincrono: inviato ad un processo/thread che non causa del


segnale.

Esso viene gestito da un signal handler, che pu essere:

gestore predefinito: per ogni segnale esiste una procedura specica


che il

kernel

esegue per gestirlo.

funzione di gestione: per ogni segnale esiste una procedura di gestione


denita dall'

utente.

Nel caso di processi multithread esistono diverse modalit di segnalazione asincrona:

inviare il segnale al thread cui il segnale si riferisce. inviare il segnale ad ogni thread del processo. inviare il segnale a specici thread del processo. denire un thread specico per ricevere tutti i segnali diretti al processo.

task 20 .

Thread di Linux

Linux non distingue tra

processi

thread :

esistono solo

Un task il usso di controllo di un programma. Per ogni task, esiste

nel kernel un'unica struttura dati, che punta ad altre strutture dati, dove i dati sono eettivamente contenuti. L'implementazione dei thread in Linux basata sul concetto di Light Weight

Process (LWP)21 , ovvero un task che condivide alcune risorse selezionate con
19 ovvero 20 ovvero 21 ovvero

gruppo di thread. operazione. processo leggero.


6

clone(), il cui vettore di flag permette di stabilire l'intensit di condivisione.


I principali ag sono:

il proprio genitore. Per creare un LWP si fa uso della funzione di libreria

CLONE_FS: condivisione delle informazioni sul le system. CLONE_VM: condivisione dello stesso spazio di memoria. CLONE_SIGHAND: condivisione dei gestori dei segnali. CLONE_FILES: condivisione dei le aperti. CLONE_THREAD: stesso processo.

Osserviamo che una

creare un thread, quindi ad invocare una invocare una

clone() con la massima intensit di condivisione equivale a pthread_create(); mentre una clone()
crea e rende eseguibile un nuovo LWP. Si tratta di una

che non preveda alcuna condivisione equivale a duplicare un processo, quindi ad La routine

funzione di libreria basata sulla

chiamata di sistema clone()22 . int clone(start_routine, stack, ags, arg, ...)


start_routine : stack : ags : arg :
funzione eseguita dal LWP.

fork(). clone()

indirizzo della cime dello stack UM del nuovo LWP. ag di intensit della condivisione.

argomenti da passare alla funzione start_routine.

chiamata di sistema clone() presenta una semantica dierente. int clone(ags, stack); ags : ag di intensit della condivisione. stack : indirizzo della cime dello stack UM del nuovo LWP. In caso fosse nullo, il glio utilizza una copia dello stack del genitore. L'esecuzione del glio inizia con l'istruzione successiva alla chiamata di sistema clone().
7

22 la