+lo \textit{scheduler} assegna la CPU ai vari processi attivi. In particolare
+prenderemo in esame i vari meccanismi con cui viene gestita l'assegnazione del
+tempo di CPU, ed illustreremo le varie funzioni di gestione.
+
+
+\subsection{I meccanismi di \textit{scheduling}}
+\label{sec:proc_sched}
+
+La scelta di un meccanismo che sia in grado di distribuire in maniera efficace
+il tempo di CPU per l'esecuzione dei processi è sempre una questione delicata,
+ed oggetto di numerose ricerche; in generale essa dipende in maniera
+essenziale anche dal tipo di utilizzo che deve essere fatto del sistema, per
+cui non esiste un meccanismo che sia valido per tutti gli usi.
+
+La caratteristica specifica di un sistema multitasking come Linux è quella del
+cosiddetto \textit{prehemptive multitasking}: questo significa che al
+contrario di altri sistemi (che usano invece il cosiddetto \textit{cooperative
+ multitasking}) non sono i singoli processi, ma il kernel stesso a decidere
+quando la CPU deve essere passata ad un altro processo. Come accennato in
+\secref{sec:proc_hierarchy} questa scelta viene eseguita da una sezione
+apposita del kernel, lo \textit{scheduler}, il cui scopo è quello di
+distribuire al meglio il tempo di CPU fra i vari processi.
+
+La cosa è resa ancora più complicata dal fatto che con le architetture
+multi-processore si deve anche scegliere quale sia la CPU più opportuna da
+utilizzare.\footnote{nei processori moderni la presenza di ampie cache può
+ rendere poco efficiente trasferire l'esecuzione di un processo da una CPU ad
+ un'altra, per cui effettuare la migliore scelta fra le diverse CPU non è
+ banale.} Tutto questo comunque appartiene alle sottigliezze
+dell'implementazione del kernel; dal punto di vista dei programmi che girano
+in user space, anche quando si hanno più processori (e dei processi che sono
+eseguiti davvero in contemporanea), le politiche di scheduling riguardano
+semplicemente l'allocazione della risorsa \textsl{tempo di esecuzione}, la cui
+assegnazione sarà governata dai meccanismi di scelta delle priorità che
+restano gli stessi indipendentemente dal numero di processori.
+
+I processi non devono solo eseguire del codice, ad esempio molto spesso
+saranno impegnati in operazioni di I/O, possono venire bloccati da un comando
+dal terminale, sospesi per un certo periodo di tempo. In tutti questi casi la
+CPU diventa disponibile ed è compito dello kernel provvedere a mettere in
+esecuzione un altro processo.
+
+Tutte queste possibilità sono caratterizzate da un diverso \textsl{stato} del
+processo, in Linux un processo può trovarsi in uno degli stati riportati in
+\tabref{tab:proc_proc_states}; ma soltanto i processi che sono nello stato
+\textit{runnable} concorrono per l'esecuzione. Questo vuol dire che, qualunque
+sia la sua priorità, un processo non potrà mai essere messo in esecuzione
+fintanto che esso si trova in uno qualunque degli altri stati.
+
+\begin{table}[htb]
+ \centering
+ \begin{tabular}[c]{|p{3cm}|c|p{8cm}|}
+ \hline
+ \textbf{Stato} & \texttt{STAT} & \textbf{Descrizione} \\
+ \hline
+ \hline
+ \textbf{Runnable} & \texttt{R} & Il processo è in esecuzione o è pronto ad
+ essere eseguito (cioè è in attesa che gli venga assegnata la CPU). \\
+ \textbf{Sleep} & \texttt{S} & Il processo processo è in attesa di un
+ risposta dal sistema, ma può essere interrotto da un segnale. \\
+ \textbf{Uninterrutible Sleep} & \texttt{D} & Il processo è in
+ attesa di un risposta dal sistema (in genere per I/O), e non può essere
+ interrotto in nessuna circostanza. \\
+ \textbf{Stopped} & \texttt{T} & Il processo è stato fermato con un
+ \macro{SIGSTOP}, o è tracciato.\\
+ \textbf{Zombie} & \texttt{Z} & Il processo è terminato ma il suo stato di
+ terminazione non è ancora stato letto dal padre. \\
+ \hline
+ \end{tabular}
+ \caption{Elenco dei possibili stati di un processo in Linux, nella colonna
+ \texttt{STAT} si è riportata la corripondente lettera usata dal comando
+ \cmd{ps} nell'omonimo campo.}
+ \label{tab:proc_proc_states}
+\end{table}
+
+Si deve quindi tenere presente che l'utilizzo della CPU è soltanto una delle
+risorse che sono necessarie per l'esecuzione di un programma, e a seconda
+dello scopo del programma non è detto neanche che sia la più importante (molti
+programmi dipendono in maniera molto più critica dall'I/O). Per questo motivo
+non è affatto detto che dare ad un programma la massima priorità di esecuzione
+abbia risultati significativi in termini di prestazioni.
+
+Il meccanismo tradizionale di scheduling di Unix (che tratteremo in
+\secref{sec:proc_sched_stand}) è sempre stato basato su delle \textsl{priorità
+ dinamiche}, in modo da assicurare che tutti i processi, anche i meno
+importanti, possano ricevere un po' di tempo di CPU. In sostanza quando un
+processo ottiene la CPU la sua priorità viene diminuita. In questo modo alla
+fine, anche un processo con priorità iniziale molto bassa, finisce per avere
+una priorità sufficiente per essere eseguito.
+
+Lo standard POSIX.1b però ha introdotto il concetto di \textsl{priorità
+ assoluta}, (chiamata anche \textsl{priorità statica}, in contrapposizione
+alla normale priorità dinamica), per tenere conto dei sistemi
+real-time,\footnote{per sistema real-time si intende un sistema in grado di
+ eseguire operazioni in un tempo ben determinato; in genere si tende a
+ distinguere fra l'\textit{hard real-time} in cui è necessario che i tempi di
+ esecuzione di un programma siano determinabili con certezza assoluta (come
+ nel caso di meccanismi di controllo di macchine, dove uno sforamento dei
+ tempi avrebbe conseguenze disastrose), e \textit{soft-real-time} in cui un
+ occasionale sforamento è ritenuto accettabile.} in cui è vitale che i
+processi che devono essere eseguiti in un determinato momento non debbano
+aspettare la conclusione di altri che non hanno questa necessità.
+
+Il concetto di priorità assoluta dice che quando due processi si contendono
+l'esecuzione, vince sempre quello con la priorità assoluta più alta, anche
+quando l'altro è in esecuzione (grazie al \textit{prehemptive scheduling}).
+Ovviamente questo avviene solo per i processi che sono pronti per essere
+eseguiti (cioè nello stato \textit{runnable}). La priorità assoluta viene in
+genere indicata con un numero intero, ed un valore più alto comporta una
+priorità maggiore. Su questa politica di scheduling torneremo in
+\secref{sec:proc_real_time}.
+
+In generale quello che succede in tutti gli Unix moderni è che ai processi
+normali viene sempre data una priorità assoluta pari a zero, e la decisione di
+assegnazione della CPU è fatta solo con il meccanismo tradizionale della
+priorità dinamica. In Linux tuttavia è possibile assegnare anche una priorità
+assoluta, nel qual caso un processo avrà la precedenza su tutti gli altri di
+priorità inferiore, che saranno eseguiti solo quando quest'ultimo non avrà
+bisogno della CPU.
+
+
+\subsection{Il meccanismo di \textit{scheduling} standard}
+\label{sec:proc_sched_stand}
+
+A meno che non si abbiano esigenze specifiche, l'unico meccanismo di
+scheduling con il quale si avrà a che fare è quello tradizionale, che prevede
+solo priorità dinamiche. È di questo che, di norma, ci si dovrà preoccupare
+nella programmazione.
+
+Come accennato in Linux tutti i processi ordinari hanno la stessa priorità
+assoluta. Quello che determina quale, fra tutti i processi in attesa di
+esecuzione, sarà eseguito per primo, è la priorità dinamica, che è chiamata
+così proprio perché varia nel corso dell'esecuzione di un processo. Oltre a
+questo la priorità dinamica determina quanto a lungo un processo continuerà ad
+essere eseguito, e quando un processo potrà subentrare ad un altro
+nell'esecuzione.
+
+Il meccanismo usato da Linux è piuttosto semplice, ad ogni processo è
+assegnata una \textit{time-slice}, cioè in intervallo di tempo (letteralmente
+una fetta) per il quale esso deve essere eseguito. Il valore della
+\textit{time-slice} è controllato dalla cosiddetta \textit{nice} (o
+\textit{niceness}) del processo. Essa è contenuta nel campo \var{nice} di
+\var{task\_struct}; tutti i processi vengono creati con lo stesso valore, ed
+essa specifica il valore della durata iniziale della \textit{time-slice} che
+viene assegnato ad un altro campo della struttura (\var{counter}) quando il
+processo viene eseguito per la prima volta e diminuito progressivamente ad
+ogni interruzione del timer.
+
+Quando lo scheduler viene eseguito scandisce la coda dei processi in stato
+\textit{runnable} associando, sulla base del valore di \var{counter}, un peso
+a ciascun processo in attesa di esecuzione,\footnote{il calcolo del peso in
+ realtà è un po' più complicato, ad esempio nei sistemi multiprocessore viene
+ favorito un processo che è eseguito sulla stessa CPU, e a parità del valore
+ di \var{counter} viene favorito chi ha una priorità più elevata.} chi ha il
+peso più alto verrà posto in esecuzione, ed il precedente processo sarà
+spostato in fondo alla coda. Dato che ad ogni interruzione del timer il
+valore di \var{counter} del processo corrente viene diminuito, questo assicura
+che anche i processi con priorità più bassa verranno messi in esecuzione.
+
+La priorità di un processo è così controllata attraverso il valore di
+\var{nice}, che stabilisce la durata della \textit{time-slice}; per il
+meccanismo appena descritto infatti un valore più lungo infatti assicura una
+maggiore attribuzione di CPU. L'origine del nome di questo parametro sta nel
+fatto che in genere esso viene generalmente usato per diminuire la priorità di
+un processo, come misura di cortesia nei confronti degli altri.
+
+I processi infatti vengono creati dal sistema con lo stesso valore di
+\var{nice} (nullo) e nessuno è privilegiato rispetto agli altri; il valore può
+essere modificato solo attraverso la funzione \func{nice}, il cui prototipo è:
+\begin{prototype}{unistd.h}
+{int nice(int inc)}
+ Aumenta il valore di \var{nice} per il processo corrente.
+
+ \bodydesc{La funzione ritorna zero in caso di successo e -1 in caso di
+ errore, nel qual caso \var{errno} può assumere i valori:
+ \begin{errlist}
+ \item[\macro{EPERM}] un processo senza i privilegi di amministratore ha
+ specificato un valore di \param{inc} negativo.
+ \end{errlist}}
+\end{prototype}
+
+L'argomento \param{inc} indica l'incremento del valore di \var{nice}:
+quest'ultimo può assumere valori compresi fra \macro{PRIO\_MIN} e
+\macro{PRIO\_MAX} (che nel caso di Linux sono $-19$ e $20$), ma per
+\param{inc} si può specificare un valore qualunque, positivo o negativo, ed il
+sistema provvederà a troncare il risultato nell'intervallo consentito. Valori
+positivi comportano maggiore \textit{cortesia} e cioè una diminuzione della
+priorità, ogni utente può solo innalzare il valore di un suo processo. Solo
+l'amministratore può specificare valori negativi che permettono di aumentare
+la priorità di un processo.
+
+In SUSv2 la funzione ritorna il nuovo valore di \var{nice}; Linux non segue
+questa convenzione, e per leggere il nuovo valore occorre invece usare la
+funzione \func{getpriority}, derivata da BSD, il cui prototipo è:
+\begin{prototype}{sys/resource.h}
+{int getpriority(int which, int who)}
+
+Restituisce il valore di \var{nice} per l'insieme dei processi specificati.
+
+ \bodydesc{La funzione ritorna la priorità in caso di successo e -1 in caso di
+ errore, nel qual caso \var{errno} può assumere i valori:
+ \begin{errlist}
+ \item[\macro{ESRCH}] non c'è nessun processo che corrisponda ai valori di
+ \param{which} e \param{who}.
+ \item[\macro{EINVAL}] il valore di \param{which} non è valido.
+ \end{errlist}}
+\end{prototype}
+\noindent (in vecchie versioni può essere necessario includere anche
+\file{<sys/time.h>}, questo non è più necessario con versioni recenti delle
+librerie, ma è comunque utile per portabilità).
+
+La funzione permette di leggere la priorità di un processo, di un gruppo di
+processi (vedi \secref{sec:sess_proc_group}) o di un utente, a seconda del
+valore di \param{which}, secondo la legenda di \tabref{tab:proc_getpriority},
+specificando un corrispondente valore per \param{who}; un valore nullo di
+quest'ultimo indica il processo, il gruppo di processi o l'utente correnti.
+
+\begin{table}[htb]
+ \centering
+ \footnotesize
+ \begin{tabular}[c]{|c|c|l|}
+ \hline
+ \param{which} & \param{who} & \textbf{Significato} \\
+ \hline
+ \hline
+ \macro{PRIO\_PROCESS} & \type{pid\_t} & processo \\
+ \macro{PRIO\_PRGR} & \type{pid\_t} & process group \\
+ \macro{PRIO\_USER} & \type{uid\_t} & utente \\
+ \hline
+ \end{tabular}
+ \caption{Legenda del valore dell'argomento \param{which} e del tipo
+ dell'argomento \param{who} delle funzioni \func{getpriority} e
+ \func{setpriority} per le tre possibili scelte.}
+ \label{tab:proc_getpriority}
+\end{table}
+
+La funzione restituisce la priorità più alta (cioè il valore più basso) fra
+quelle dei processi specificati; dato che -1 è un valore possibile, per poter
+rilevare una condizione di errore è necessario cancellare sempre \var{errno}
+prima della chiamata alla funzione, per verificare che essa resti uguale a
+zero.