I thread sono nati per alleggerire il parallelismo su macchine lente Non sempre i thread sono vantaggiosi, se usati troppo sono svantaggiosi rispetto ai processi tradizionali. Un processo contiene
I thread dello stesso processo condividono tutte le risorse aperte, con le dovute problematiche di concorrenza e sincronizzazione. Per questo sono stati introdotti i meccanismi di mutex tipici dei processi, anche per i thread. L'esempio classico sono i server, in cui posso creare tanti thread e all'occorrenza risvegliarli, inoltre su sistemi multicore posso dividere i thread sui vari core, per gestire il carico.
L'overhead di creazione/distruzione di thread era di un fattore 10 rispetto ai processi nei primi sistemi linux che lo implementavano.
Capostipite dei thread sono i solaris thread, che venivano usati da Solaris (girava su SPARC) Su windows sono venuti sfruttati bene da windows NT. I threads vennero introdotti da una libreria thread scritta da uno studente di Berkley e consistevano in una esecuzione di diverse funzioni in modo trasparente al kernel.
Quindi i thread possono essere sia kernel che utente
Utile per partizionare un applicazione Si utilizza un thread diverso per ogni funzione, ad esempio si dedica un thread alla sola interazione utente, in modo da avere una maggiore reattività agli input.
La prima applicazione dei thread è stata un foglio elettronico, in cui abbiamo un thread per input, uno per video e uno per il calcolo.
Non è detto che un problema si riesca a mappare bene su un'architettura multicore, ad esempio perchè la complessità dei thread è sbilanciata, es: thread input o display sono molto più leggeri del thread computing. Vantaggio principale è dare reattività all'esperienza utente.
Un thread detto dispatcher riceve richieste di servizio e le invia ai vari thread. Si mappa molto bene su architetture a cluster, in cui abbiamo un core principale(dispatcher) e dei worker core con memoria condivisa a cui viene inviato il lavoro. Questa architettura presenta dei vantaggi per il risparmio energetico perchè posso tenere spenti i worker core finchè non arriva del lavoro da assegnargli.
Costituito da elementi con ingresso e uscita (es: bash pipe) In questo caso il secondo elemento ha un buffer di dati in ingresso e può elaborare senza dover scrivere/leggere da memoria. Vantaggiosa per effettuare delle ricerche, in quanto non serve elaborare tutti i dati per trovare un risultato.
Viene implementato uno strato di supporto runtime a livello utente per gestire i thread Il supporto si occupa dello scheduling dei thread attivi di un processo. Simile a co-routine nella programmazione. Difficile sfruttare i sistemi multicore Facile da implementare
Se un thread è bloccato non blocca l'intero processo come nel caso utente. Serve implementare delle specifiche chiamate di sistema e modificare il kernel.
Le principali soluzioni per far comunicare i thread sono:
Concorrenza nel caso di parallelismo reale può portare ad eseguire insieme i due processi In un sistema monoprocessore i due processi verranno eseguiti sequenzialmente ma non si sa in quale ordine
POSIX è un modo per standardizzare le interfacce dei sistemi operativi, per migliorare la portabilità del codice.
RIPASSARE Il carico dei processi di solito avviene a burst, seguiti dall'attesa per l'I/O Lo scheduler preemptive è più difficile da gestire rispetto ad uno normale