I Thread
Anche detti processi leggeri.
Un thread è un singolo flusso di istruzioni, all’interno di un processo, che lo scheduler può fare eseguire separatamente e concorrentemente con il resto del processo.
Un thread può essere pensato come una procedura che lavora in parallelo con altre procedure all’interno di un processo.
Per eseguire in parallelo con il resto del processo, un thread deve possedere delle strutture dati (un proprio contesto) cioè un proprio ambiente di esecuzione, per realizzare il proprio flusso di controllo.
Ogni processo ha il proprio contesto, ovvero il proprio Process ID, Program Counter, Stato dei Registri, Stack, Codice, Dati, File Descriptors, Entità IPC, Azioni dei segnali.
Un Processo può avere più thread.
Tutti i thread di uno stesso processo condividono le risorse del processo (dati globali e CPU) ed eseguono nello stesso spazio utente.
Ciascun Thread può usare tutte le variabili globali del processo e condivide la tabella dei descrittori di file del processo.
Ciascun thread in più potrà avere anche dei propri dati locali e un proprio Stack, un proprio Program Counter, un proprio Stato dei Registri e una propria variabile errno.
Dati globali ed entità del Thread (Dati, Stack, Codice, Program Counter, Stato dei Registi) rappresentano lo stato di esecuzione del singolo thread.
Vantaggi
- visibilità dei dati globali: condivisione di oggetti semplificata;
- più flussi di esecuzione;
- gestione semplice di eventi asincroni (I/O per esempio);
- comunicazioni veloci: tutti i thread di un processo condividono lo stesso spazio di indirizzamento, quindi le comunicazioni tra thread sono più semplici delle comunicazioni tra processi;
- context switch veloce: nel passaggio da un thread ad un altro di uno stesso processo
viene mantenuto buona parte dell’ambiente.
Svantaggi
- concorrenza: occorre gestire la mutua esclusione per evitare che più thread utilizzino in maniera scoordinata i dati condivisi, modificandoli in momenti sbagliati.
Lo standard IEEE POSIX definisce un’interfaccia unica per l’utilizzo dei thread. I thread POSIX sono noti come Pthread. Le API per Pthread distinguono le funzioni in 3 gruppi:
Thread management: funzioni per creare, eliminare, attendere la fine dei pthread.
Mutex: funzioni per supportare la sincronizzazione in ambienti concorrenti, garantendo la mutua esclusione. Comprende funzioni per creare, acquisire, rilasciare ed eliminare il mutex per una risorsa.
Condition variables: funzioni a supporto di una sincronizzazione più complessa, dipendente dal valore di variabili speciali, Comprende funzioni per creare e eliminare la struttura per la sincronizzazione, per attendere e segnalare le modifiche delle variabili.
Convenzione sui nomi delle funzioni:
Gli identificatori della libreria dei Pthread iniziano con pthread_:
pthread_indica gestione dei pthread in generale;pthread_ attr_funzioni per gestione proprietà dei thread;pthread_mutex_gestione mutua esclusione;pthread_mutexattr_proprietà delle strutture per mutua esclusione;pthread_cond_gestione delle variabili di condizione;pthread_condattr_proprietà delle variabili di condizione;pthread_key_dati speciali dei thead;
il file pthread.h contiene le definizioni dei pthread.
Per utilizzare la libreria pthread, è necessario includerla nel codice sorgente (#include<pthread.h>) e aggiungerla in fase di linking (compilando con gcc, dovremo aggiungere la flag -lpthread che linka la libreria libthread.so).
#include<pthread.h>
int pthread_create ( pthread_t *thread, pthread_attr_t *attr, void* (*start_routine)(void *), void * arg );
La funzione crea una thread e lo rende eseguibile, cioè lo mette a disposizione dello scheduler che, quando potrà, lo farà partire. Questi i suoi parametri di input:
pthread_thread *thread: un puntatore a un identificatore di thread, in cui verrà scritto l’ID del thread creato;pthread_attr_t *attr: il riferimento alla struttura dati contenente caratteristiche specifiche con cui creare il thread; può essere posto a NULL per avere il comportamento di default;void* (start_routine)(void*): è il riferimento alla funzione da far eseguire al thread; la funzione prevede come unito argomento un puntatore a un tipo generico e restituisce un puntatore a un tipo generico;void* arg: è il puntatore passato in input astart_routine; tale puntatore solitamente punta ad una area di memoria allocata dinamicamente; può essere NULL, nel caso in cui non si vogliano passare argomenti alla routine.
La funzione pthread_create restituisce un valore di tipo intero; tale intero è 0 se il thread è stato creato correttamente, altrimenti è un codice d’errore.
#include<pthread.h>
void pthread_exit(void *retval);
La funzione non ritorna al chiamante e non ha condizioni di errore.
La funzione pthread_exit termina il thread chiamante e restituisce un valore di uscita tramite la variabile retval di tipo puntatore a tipo generico (void*).
Se il thread è stato creato come joinable, il valore di uscita viene mantenuto nello stack del thread per risultare disponibile al processo e consultabile tramite la chiamata a pthread_join; la memoria occupata dallo stack del thread già terminato viene rilasciata solo dopo che un altro thread ha invocato la pthread_join per conoscere il risultato del thread terminato.
Quando il thread termina e il processo ha altri thread in esecuzione, le risorse condivise del processo (mutex, condition variables, semafori e descrittori dei file) non sono rilasciate; se invece il thread che ha invocato la pthread_exit era l’ultimo in esecuzione in quel processo, allora il processo viene terminato; se non è importante restituire il valore di uscita, retval può essere NULL.
#include<pthread.h>
int pthread_join(pthread_t thread, void **retval);
Un thread può attendere la terminazione di un altro thread dello stesso processo invocando pthread_join. Occorre conoscere l’identificatore del thread di cui vogliamo attendere la terminazione.
I parametri di input sono: pthread_t thread, cioè l’identificatore del thread di cui vogliamo attendere la terminazione, e void **retval, l’indirizzo del puntatore generico, in cui verrà memorizzato il valore di uscita del thread identificato dal primo argomento.
La funzione restituisce 0 in caso di successo, altrimenti un codice d’errore.
Sezioni
- Blog (1)
- DMC News (5)
- e-Learning (6)
Tag
Articoli recenti
- Sponsor checking 23 Marzo 2026
- Laboratorio immersivo multisensoriale 26 Novembre 2025
- I Thread 21 Novembre 2025
- Finalisti al “Le Fonti Awards” 4 Settembre 2025
- La pila ISO/OSI e TCP/IP 10 Giugno 2025


