PROCESSI






Un sistema operativo si dice multitasking, quando è in grado di eseguire più programmi contemporaneamente. E' importante distinguere fra programma inteso come "contenitore di istruzioni" e programma inteso come entità "in corso di esecuzione". Un programma in corso di esecuzione prende il nome di processo (o task). Quindi mentre un programma è un'entità statica che descrive le azioni da compiere, un processo è un'entità dinamica che rappresenta l'esecuzione di tali azioni. Il meccanismo che il SO adotta per eseguire “in parallelo” più processi (processi concorrenti) è denominato Time Sharing. Esso consiste nell’assegnare la CPU  per un quanto di tempo detto time-slice, prefissato ad ogni processo.  Allo scadere del quanto, l’esecuzione del processo viene sospesa e la CPU viene assegnata ad un altro processo. Questa tecnica è chiamata prehemptive multitasking

Il problema più importante dei sistemi multitasking è l'assegnazione delle risorse richieste dai vari processi. Può verificarsi infatti che più processi chiedano contemporaneamente una determinata risorsa unica non condivisibile (es. la stampante): in questo caso se, all’atto in cui un processo ne fa richiesta, essa è utilizzata da un altro processo, l’esecuzione del processo richiedente viene sospesa immediatamente, il processo richiedente viene inserito in una coda d’attesa e solo quando la risorsa verrà rilasciata e nessun altro processo della coda lo precede, potrà acquisire la risorsa e riprendere l’esecuzione. 

Un altro problema riguarda l’accesso alle periferiche. Poiché le operazioni di I/O sui dispositivi sono estremamente lente rispetto alla velocità del processore, la richiesta da parte di un processo di un operazione di I/O provoca la sospensione del processo stesso finché l’operazione non è stata completata ( il meccanismo hardware messo in gioco è ovviamente l’interrupt )
Da quanto esposto possiamo concludere che un processo può trovarsi in uno di questi tre stati 


Nel corso della sua esecuzione quindi un processo passa da uno stato all'altro secondo come illustrato dal diagramma di transizione




 

La gestione dei processi pronti (ready) viene implementata invece che da una coda singola da un set di code ciascuna con una priorità definita. Ad ogni processo viene assegnata una priorità di modo che quando il processo va in stato di pronto viene inserito nella coda con la priorità corrispondente (Round Robin). 

Il processo che va in esecuzione  è il primo della coda a priorità più elevata.  Se in questa non ci sono processi in attesa viene eseguito il primo della coda a priorità di livello inferiore e così via. 

Questo meccanismo così come l'abbiamo descritto non è molto efficiente: certi processi di sistema (cioè quelli lanciati dal SO) oppure processi utente di una certa importanza, possono essere nfatti costretti a lunghe attese (Starvation), compromettendo il corretto funzionamento del sistema.
Il problema si risolve con la gestione dinamica delle priorità. 
All’atto della creazione viene assegnato al processo un determinato livello di priorità  (priorità statica) . Un criterio comunemente usato per es. è dare ai processi che svolgono prevalentemente operazioni I/O (I/O-Bound) la priorità più elevata e ai processi che usano prevalentemente la CPU (CPU-Bound) quella più bassa .
Nel corso dell'esecuzione del processo la priorità può essere cambiata. Per es. un processo che entra per la prima volta nel sistema viene inserito nella coda a più alta priorità. Al primo quanto di tempo, se il processo non ha teminato, viene inserito nella coda a priorità immediatamente inferiore. (algoritmo di Shortest Elapsed Time)

Il componenete del SO che stabilisce i criteri per l’assegnazione della CPU ai processi è chiamato Scheduler. Lo scheduler utilizza un modulo chiamato Dispatcher, che svolge tutte le operazioni necessarie per far compiere al processo la transizione da uno stato ad un altro. La più importante di queste operazioni è  il salvataggio delle informazioni relative  al processo rilasciato e il ripristino di quelle del nuovo processo da mandare in esecuzione (Context Switching)
Ai fini dell'assegnazione della priorità va tenuto conto di una importante distinzione fra i processi:  processi background e processi foreground. 

I processi background non interagiscono con l’utente mentre i processi foreground generalmente attendono una qualche forma di input. Tipici processi background sono i daemons (terminologia di linux/unix): si tratta di  processi che vengono mandati in esecuzione dal SO periodicamente o in seguito al verificarsi di un qualche evento. Ai processi in foreground viene assegnata una priorità maggiore.
Linux e Windows utilizzano diverse code di priorità corrispondenti ad altrettanti livelli di priorità. Valori di priorità più bassi indicano maggiore priorità. 

Linux assegna ai processi utente una priorità compresa fra 60 e 100. Per i processi di sistema i valori sono al di sotto di 40. Il superuser può assegnare ad un processo, per es. un comando una priorità il cui valore più basso è  40. 

 

In Windows, ad ogni processo viene assegnata una delle seguenti quattro possibili classi di priorità :


Le informazioni sui processi attivi del sistema vengono memorizzate in apposite tabelle.  La tabella dei processi (in linux: task_struct) contiene lo stato, la priorità, il tempo d'uso, il PID, l'ID dell'utente del processo etc..

Il PID (process identifier) è un numero di 32 bit che identifica il processo.

L'insieme delle informazioni che individuano un processo prende il nome di descrittore di processo