Un thread è un processo leggero.
Un processo è una sequenza di codice in esecuzione, così come tutte le strutture dati di supporto (mappa della memoria, risorse aperte, stack, ecc.).
Se si vuole avere del codice che venga eseguito in parallelo (sia perché rende la programmazione più facile, sia perché si vuole trarre vantaggio dalle architetture multi-CPU), si possono eseguire più processi, o più thread all'interno di un processo.
Un processo può contenere uno o più thread, e tutti i thread nello stesso processo condividono la mappa della memoria, le risorse aperte, ma hanno i propri stack.
Ci sono pro e contro per ogni approccio. Per esempio, l'uso dei processi vi permette di eseguire programmi indipendenti allo stesso tempo che potrebbero non essere stati specificamente scritti per lavorare insieme. L'uso dei processi ti dà anche una migliore protezione contro le interferenze involontarie tra i compiti (che possono essere maligne o solo errori di programmazione) - questo è il motivo per cui Chrome usa un processo per scheda, per esempio, invece dei thread. Questo è anche il motivo per cui Chrome tipicamente occupa molta più memoria di Firefox, se si apre un gran numero di schede.
D'altra parte, usando i thread si risparmia memoria, poiché molte cose possono essere condivise tra i thread. Rendono anche la programmazione più facile perché diversi thread nello stesso processo possono comunicare semplicemente usando variabili condivise (con un'appropriata sincronizzazione).
Ci sono anche programmi che permettono di scegliere tra processo e thread - un esempio che mi viene in mente è il server web open source Apache.
Di default, Apache genera un nuovo processo per ogni connessione client, e ogni processo serve solo un client. Tuttavia, è possibile configurarlo per usare i thread. L'uso dei thread lo rende più veloce e usa meno memoria in scenari altamente caricati, ma potenzialmente a spese della sicurezza (se c'è un bug in Apache e un attaccante lo trova, potrebbe essere in grado di accedere ad altri thread' dati).