Schedulazione dei Processi
Il numero dei processi attivi simultaneamente è molto maggiore del numero delle CPU disponibili. L'impressione di parallelismo di esecuzione dei processi è data dedicando a ciascun processo un limitato tempo di CPU e alternando velocemente a rotazione su tutti i processi attivi.
L'algoritmo di gestione dei processi si chiama di schefdulazione.
La vita di un processo è rappresentabile da un Diagramma a Stati Finiti, con stati rappresentati da cerchi e transizioni da frecce.
Tutti gli algoritmi Unix e di rete sono rappresentabili da Diagrammi a Stati Finiti
La seguente è un'immagine semplificata della Schedulazione in Linux (gli stati sono molti di più).
Quando l'eseguibile viene lanciato, la libreria del loader, con cui tutti i programmi Linux sono linkati, lo prepara all'esecuzione e lo porta nello stato Ready.
Vi possono essere più processi nello stato Ready, in attesa di esecuzione. Questi sono in coda nella Run Queue, che è sortizzata per Priorità Dinamica.
Ad intervalli regolari il kernel preleva il primo processo dalla Run Queue e lo porta in una CPU resasi disponibile, nello stato Run User. Il processo esegue il proprio codice.
Spesso durante l'esecuzione il processo deve invocare servizi del kernel tramite system calls e passa nello stato Run System. In questo stato sta eseguendo codice che si trova nel kernel, e non è interrompibile. Le system calls sono progettate per completare rapidamente con un return, dopo il quale il processo ritorna nello stato Run User.
Questo ciclo si ripete più volte, con una riduzione continua della Priorità Dinamica finchè o il processo esce spontaneamente oppure scade il suo tempo, detto Time Slice. La Time Slice è dell'ordine di 10 millisecondi.
Allo scadere del tempo, se non vi sono altri processi in attesa di esecuzione, la Time Slice viene rinnovata, altrimenti il processo viene prelazionato e rimandato nella Run Queue, probabilmente in fondo se la sua Priorità Dinamica è diminuita.
Nel frattempo viene schedulato il primo processo in coda. La doppia operazione di prelazione e schedulazione è in verità una singola operazione di modifica di un puntatore interno e si chiama context switch.
Il processo può uscire spontaneamente dalla CPU con chiamate di sistema delle classi exit()
o abort()
. In tal caso va temporaneamente nello stato Zombie. Il processo non è subito rimosso poichè può possedere risorse che altri processi del suo CGroup stanno usando.
Quando il kernel è sicuro che nessun altro processo punti alle risorse dello Zombie, questo subisce l'operazione di reaping o cleaning, e tutti i suoi dati rappresentativi sono tolti dalla tabella dei processi.
Il processo può uscire dalla CPU anche quando è in attesa di operazioni esterne alla CPU stessa, come una scrittura su disco o l'input da tastiera. In tal caso viene posto nello stato Sleeping e gli viene associato un canale di comunicazione. Nello stato Sleeping il processo si vede aumentata la Priorità Dinamica.
Quando l'evento esterno è completo, comunica la terminazione al canale di comunicazione del processo in sleeping, a cui avviene l'operazione di wakeup e il processo viene riportato nello stato Ready, probabilmente verso la testa della Run Queue visto che la sua priorità è aumentata.
Per evitre ingiustizie, anche ai processi che passano molto tempo nella Run Queue è aumentata la Priorità Dinamica, per permettere loro di avanzare nella coda.
Attenzione
Il meccanismo descritto sopra fa parte del tipo di schedulazione detto Time Sharing ed è di gran lunga il più usato.
Ma esistono altri algoritmi di schedulazione, per sempio ma non solo il Real Time, che possono essere applicati a determinati processi.
In generale i processi Real Time sono molto avidi di CPU ed altre risorse, e sono normalmente evitati se non per applicazioni molto particolari.
Esistono inoltre altri stati non descritti dal diagramma, come Suspended, Blocked e Traced, poichè di impatto minore sulla comprensione globale.
Priorità dei Processi
Priorità Dinamica
E' un valore associato ad ogni processo che cambia a seconda della sua storia. E' aumentata in Sleeping e diminuita in Running.
Il modello applicato favorisce i processi cosiddetti I/O Bound e sfavorisce i processi CPU Bound, per impedire che diventino CPU Hogs (maialini della CPU), e che monopolizziono le risorse computazionali a scapito degli altri. E' applicata solo nella schedulazione Time Sharing.
La gestione della Priorità Dinamica è sospesa, per evitare burocrazia, se il carico di sistema (system load) è al di sotto di una soglia minima.
Il carico di sistema è indicato dal numero medio dei processi in attesa nella Run Queue a breve periodo, tipicamente nell'arco degli ultimi 5 secondi. La soglia è tipicamente 0.8
.
La priorità è un valore numerico col range potenziale tra 0
e 127
, ma funziona a rovescio delle aspettative umane, ed è più propriamente chiamato indice di priorità. Quanto è più basso tale indice, tanto maggiore è la priorità intesa in termini umani, e viceversa.
Non tutto il range dell'indice è utilizzato, dipende dalle implementazioni Unix. In Linux tipicamente il range della priorità dinamica è tra 0
e 40
, con un valore iniziale di 20
.
I processi di sistema posson anche avere indice di priorità negativo, che li fà passare davanti a tutti i processi utente.
Priorità nice
Questo è un offset all'indice di priorità dinamica e che si somma con esso per determinare la priorità effettiva.
Il suo valore va da -20
a 20
e di default è 0
. I processi di utenti normali possono solo dare un nice positivo, cioè diminuendosi la priorità (umana). Solo il superuser può dare ai processi valori di nice negativi, per aumentarne la priorità relativa.
Il comando nice
è interno della shell e va prefisso al programma a cui si applica:
nice -10 ./pippo.sh
Questo lancia la procedura pippo.sh
con una priorità diminuita di 10 punti (aumento dell'indice di priorità).
L'amministratore può dare invece il comando:
nice --10 ./pippo.sh
che ne aumenta di 10 punti la priorità relativa. Il primo segno meno è l'indicatore di opzione, il secondo è il vero segno meno algebrico.
Quando gli utenti normali lanciano un processo in background il suo nice
è automaticamente aumentato di 4 punti.