:: Riassunto capitolo 5 - I thread ::
Torna alla pagina di Sistemi Operativi
5.1 Generalità
Thread = unità base dell'utilizzo della CPU. Comprende:
- id
- program counter
- set di registri
- stack
Condivide codice, dati e altre risorse con gli altri thread appartenenti allo stesso processo.
Processo tradizionale = 1 thread.
5.1.1 Motivazioni
- Creare processi è costoso (tempo e risorse, + cambio di contesto)
- Insensato creare più processi per fare la stessa cosa (eg un server web con più processi)
5.1.2 Benefici
- Prontezza di risposta: anche se una parte di una appli è bloccata, gli altri thread possono andare avanti
- Condivisione di risorse: stesso spazio di indirizamento, ma più thread che operano
- Economia: meno costoso creare thread che processi; meno costoso il cambio di contesto tra thread
- Utilizzo di architetture multiprocessore: un thread per processore => esecuzione parallela
5.1.3 Thread nello spazio utente e nello spazio kernel
User thread = il kernel non ne sa niente
Kernel thread = gestiti dal kernel
=> paragrafo 5.2
5.1.4 Le librerie di thread
2 vie:
- libreria nello spazio utente => user thread
- libreria a livello kernel => kernel thread
5.2 Modelli multithread
Tra user thread e kernel thread deve esistere una relazione: i modelli multithread ci dicono quale
5.2.1 Il modello molti a uno
Molti user thread mappati in un kernel thread
Problemi:
- se un thread si blocca (eg chiamata I/O), blocca anche tutti gli altri
- un kernel thread = gira in 1 processore => non sfrutta i sistemi multiprocessore
5.2.2 Il modello uno a uno
1 user thread = 1 kernel thread
Pro: maggior concorrenza
Contro: overhead nella creazione => molti SO limitano il numero max di kernel thread
5.2.3 Il modello molti a molti
Molti user thread = un po' di kernel thread (stesso numero, o meno)
Prende i vantaggi e non gli svantaggi dei precedenti 2 modelli
Variante. il modello a 2 livelli = posso usare il molti a molti, o mappare direttamente un user thread in un kernel thread.
5.3 Problematiche relative ai thread
5.3.1 Le chiamate fork() ed exec()
Se un thread fa una fork, duplica se stesso o l'intero processo?
=> 2 versioni di fork, una per ogni scopo.
5.3.2 Cancellazione
Cancellare un thread = terminarlo prima che lui finisca normalmente.
Thread target = il thread che sta per essere cancellato.
La cancellazione può avvenire in 2 modi:
- asincrona = viene ucciso subito
- differita = il target controlla periodicamente se va terminato, e ha la possibilità di morire graziosamente
Problema: cancello un thread che sta usando risorse condivise => inconsistenza dei dati (specialmente con cancellazione asincrona) => meglio la cancellazione differita => esistono i punti di cancellazione dove un thread può morire in modo sicuro.
5.3.3 La gestione dei segnali
Segnali sincroni = consegnati allo stesso processo che ha eseguito l'operazione che ha causato il segnale.
Segnali asincroni = generati da eventi esterni al processo.
Ma tutti funzionano così:
- un evento genera un segnale
- il segnale viene consegnato ad un processo
- il processo lo gestisce
Chi gestisce il segnale:
- il gestore di segnali di defaul
- il gestore di segnali definito dall'utente
=> se ho molti thread nel processo, quale di essi gestisce il segnale?
- il thread che l'ha causato <= segnali sincroni
- tutti i thread
- alcuni thread
- un thread che fa gestione dei segnali
Il problema c'è con gli asincroni: alcuni vanno dati a tutti i thread, altri no. Cmq un segnale non può essere ripetuto, e va gestito 1 sola volta => viene dato al primo thread che non lo rifiuta, di solito.
In certe versioni di multithread si può specificare quali segnali un thread riceve e quali invece no.
5.3.4 Gruppi di thread
Esempio: server web che usa un thread per servire le richieste.
Problemi:
- quanto tempo ci metto a creare un nuovo thread = quanto tempo attende il mio client?
- così facendo non ho limiti al numero di thread che creo
=> pool di thread (pool = gruppo) = ne creo un po' in partenza, e do la richiesta al primo libero. Se non ce n'è nessuno, la richiesta attende.
Vantaggi:
- più veloce che nemmeno creare un thread nuovo ogni volta
- limite massimo al numero di thread in contemporanea
5.3.5 Dati specifici dei thread
I thread di un processo condividono i dati del processo => ma hanno anche bisogno di dati propri.
5.3.6 Attivazione dello schedulatore
Modello molti a molti e a 2 livelli = comunicazione tra kernel e libreria dei thread => molti SO che hanno sti sistemi usano il lightweight process = LWP
LWP = struttura dati intermedia tra processo e thread.
L'LWP appare alla libreria dei thread come un processore virtuale su cui schedulare il thread utente.
Se si blocca il kernel thread, si blocca anche l'LWP e infine l'user thread => necessario un LWP per ogni chiamata bloccante.
Un appli decide quanti LWP avere.
Attivazione dello schedulatore = schema di comunicazione tra kernel e libreria dei thread.
Il kernel fornisce a un'appli un certo numero di processori virtuali => l'appli schedula per conto suo i suoi thread sui processori virtuali disponibili..
Upcall = il kernel deve informare l'applicazione di certi eventi => la libreria di thread ha un gestore di upcall.
Eg: un thread sta per bloccarsi => il kernel informa la libreria => essa rischedula i suoi thread.
Il thread bloccato si sblocca => altra upcall => altra rischedulazione.
5.4 Pthread
...
5.5 I thread di Windows XP
...
5.6 I thread di Linux
...
5.7 I thread di Java
...
Torna alla pagina di Sistemi Operativi