Task e programmazione concorrente
Un'applicazione può avere più compiti, detti comunemente task, da portare avanti contemporaneamente. Ad esempio, i task di un editor di testo potrebbero essere:
- gestione degli eventi generati dal mouse
- gestione dell'input da tastiera
- gestione dell'output a video
- gestione della struttura dati del testo
- controllo ortografico
- salvataggio periodico dei dati
Implementare singolarmente ciascuna di queste attività è relativamente semplice, ma scrivere un programma sequenziale che le faccia tutte è molto più difficile, perchè bisogna fare in modo che esso "salti" da un'attività all'altra e determinare i momenti in cui ciò avviene.
Se, invece, il linguaggio utilizzato offre i costrutti per la programmazione concorrente, cioè i costrutti per
- definire flussi di esecuzione sequenziale indipendenti per i vari task
- eseguire i flussi concorrentemente
si può guadagnare in termini di:
- semplicità di programmazione
- efficienza di esecuzione, se si ha parallelismo:
- tra il lavoro di CPU di un task e il lavoro di I/O di un altro task
- tra il lavoro di CPU di due o più task (possibile solo su sistemi con processori multipli)
Programmazione concorrente con i processi
Il linguaggio C (ad esempio) offre funzioni di libreria che consentono di realizzare i flussi mediante processi. Questa soluzione ha però alcuni svantaggi:
- siccome ci sono numerosi processi, i context switch sono frequenti e lo scheduling è più complesso, quindi aumenta l'overhead
- ogni processo accede solo alla propria memoria, però i flussi di esecuzione hanno bisogno di condividere dati: il problema è risolvibile (mediante le comunicazioni esplicite tra processi, cioè lo scambio di messaggi), ma in modo non semplice e non naturale.