
I thread
I processi non sono adatti alla scrittura di applicazioni fortemente cooperanti, a tal fine sono stati definiti i thread, indicati a realizzare sottoattività e non un compito completo. Sfruttano al meglio le architetture multiprocessore. Interagiscono col SO tramite system call progettate in modo da poter essere utilizzate da più thread. Una delle principali applicazioni dei thread è di organizzare l'esecuzione di lavori in foreground e background, per esempio mentre uno gestisce l'I/O, altri eseguono calcoli.
Il processo pesante è l'insieme della sua immagine e dalle risorse che sta utilizzando: l'immagine è costituita dal Process ID, Program Counter, Registri, stack, codice, dati ecc.. Le risorse sono i file aperti, processi figli e dispositivo di I/O. Quando avviene il context switch il SO deve compiere molteplici operazioni.
Il processo leggero è l'unione di due componenti: esecuzione del codice e le risorse che utilizza. La parte del processo alla quale viene assegnata la CPU e quello leggero, quella che possiede le risorse è quello pesante.
Un thread è un segmento di codice che viene eseguito all'interno di un processo pesante, che condivide con esso dati e risorse. Ha un insieme di elementi chiamato TCB: ID, program counter, registri, stato, contesto, stack, spazio di memoria, puntatore al PCB. Dati globali e TCB locale rappresentano lo stato del singolo thread.
Col termine multithreading si indica la molteplicità di esecuzione in un processo pesante. Per un sistema multithread i programmi devono avere la proprietà di thread safeness.
In base alla capacità di un sistema di gestire a livello kernel i thread, abbiamo 4 scenari: singolo processo e thread, singolo processo e multiplo thread, multiplo processo e singolo thread e multiplo processo e multiplo thread. Li riscontriamo in 4 ambienti operativi: MS-DOS(1-1), UNIX(più processi, 1 thread), JVM(un processo, più thread), Linux Windows e Solaris(più processi e più thread).
I thread vengono creati in due livelli:
- User level: implementanti grazie a librerie, e sono di proprietà esclusiva del processi che li ha creati. Il kernel ignora la loro presenza. I vantaggi sono i tempi di switching ridotti, la flessibilità e la portabilità. Gli svantaggi sono che non è possibile effettuare system call senza sospendere se stesso e il processo, e non è possibile il parallelismo fisico dato che sono interni al processo.
- Kernel level: viene utilizzato a livello di nucleo, i vantaggi sono che i thread sono schedulati in modo autonomo e quindi se un thread si sospende può evolvere un secondo thread generato dallo stesso processo, si sfrutta il parallelismo fisico, e lo stesso kernel puòoo essere scritto come sistema multithread. Lo svantaggio principale è dovuto ai tempi di context switch dato che deve gestire la copresenza di processi e thread.
- Soluzioni miste: come quella implementatta in Solaris, che combina le proprietà di entrambi. I Vantaggi sono che si ha il parallelismo fisico e la chiamata al kernel non blocca nessun processo.