+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
+sez.~\ref{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.
+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
+sez.~\ref{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,\footnote{per alcune delle quali
+ sono state introdotte delle varianti 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 i processi ordinari hanno tutti
+una priorità assoluta nulla; quello che determina quale, fra tutti i processi
+in attesa di esecuzione, sarà eseguito per primo, è la cosiddetta
+\textsl{priorità dinamica},\footnote{quella che viene mostrata nella colonna
+ \texttt{PR} del comando \texttt{top}.} che è chiamata così proprio perché
+varia nel corso dell'esecuzione di un processo.
+
+Il meccanismo usato da Linux è in realtà piuttosto complesso,\footnote{e
+ dipende strettamente dalla versione di kernel; in particolare a partire
+ dalla serie 2.6.x lo scheduler è stato riscritto completamente, con molte
+ modifiche susseguitesi per migliorarne le prestazioni, per un certo periodo
+ ed è stata anche introdotta la possibilità di usare diversi algoritmi,
+ selezionabili sia in fase di compilazione, che, nelle versioni più recenti,
+ all'avvio (addirittura è stato ideato un sistema modulare che permette di
+ cambiare lo scheduler a sistema attivo).} ma a grandi linee si può dire che
+ad ogni processo è assegnata una \textit{time-slice}, cioè un intervallo di
+tempo (letteralmente una fetta) per il quale, a meno di eventi esterni, esso
+viene eseguito senza essere interrotto. Inoltre la priorità dinamica viene
+calcolata dallo scheduler a partire da un valore iniziale che viene
+\textsl{diminuito} tutte le volte che un processo è in stato \textbf{Runnable}
+ma non viene posto in esecuzione.\footnote{in realtà il calcolo della priorità
+ dinamica e la conseguente scelta di quale processo mettere in esecuzione
+ avviene con un algoritmo molto più complicato, che tiene conto anche della
+ \textsl{interattività} del processo, utilizzando diversi fattori, questa è
+ una brutale semplificazione per rendere l'idea del funzionamento, per una
+ trattazione più dettagliata, anche se non aggiornatissima, dei meccanismi di
+ funzionamento dello scheduler si legga il quarto capitolo di
+ \cite{LinKernDev}.} Lo scheduler infatti mette sempre in esecuzione, fra
+tutti i processi in stato \textbf{Runnable}, quello che ha il valore di
+priorità dinamica più basso.\footnote{con le priorità dinamiche il significato
+ del valore numerico ad esse associato è infatti invertito, un valore più
+ basso significa una priorità maggiore.} Il fatto che questo valore venga
+diminuito quando un processo non viene posto in esecuzione pur essendo pronto,
+significa che la priorità dei processi che non ottengono l'uso del processore
+viene progressivamente incrementata, così che anche questi alla fine hanno la
+possibilità di essere eseguiti.
+
+Sia la dimensione della \textit{time-slice} che il valore di partenza della
+priorità dinamica sono determinate dalla cosiddetta \textit{nice} (o
+\textit{niceness}) del processo.\footnote{questa è una delle tante proprietà
+ che ciascun processo si porta dietro, essa viene ereditata dai processi
+ figli e mantenuta attraverso una \func{exec}; fino alla serie 2.4 essa era
+ mantenuta nell'omonimo campo \texttt{nice} della \texttt{task\_struct}, con
+ la riscrittura dello scheduler eseguita nel 2.6 viene mantenuta nel campo
+ \texttt{static\_prio} come per le priorità statiche.} L'origine del nome di
+questo parametro sta nel fatto che generalmente questo viene usato per
+\textsl{diminuire} la priorità di un processo, come misura di cortesia nei
+confronti degli altri. I processi infatti vengono creati dal sistema con un
+valore di \var{nice} nullo e nessuno è privilegiato rispetto agli altri;
+specificando un valore positivo si avrà una \textit{time-slice} più breve ed
+un valore di priorità dinamica iniziale più alto, mentre un valore negativo
+darà una \textit{time-slice} più lunga ed un valore di priorità dinamica
+iniziale più basso.
+
+Esistono diverse funzioni che consentono di modificare la \textit{niceness} di
+un processo; la più semplice è funzione \funcd{nice}, che opera sul processo
+corrente, il suo prototipo è:
+\begin{prototype}{unistd.h}
+{int nice(int inc)}
+ Aumenta il valore di \var{nice} per il processo corrente.
+
+ \bodydesc{La funzione ritorna zero o il nuovo valore di \var{nice} in caso
+ di successo e -1 in caso di errore, nel qual caso \var{errno} può assumere
+ i valori:
+ \begin{errlist}
+ \item[\errcode{EPERM}] non si ha il permesso di specificare un valore
+ di \param{inc} negativo.
+ \end{errlist}}
+\end{prototype}
+
+L'argomento \param{inc} indica l'incremento da effettuare rispetto al valore
+di \var{nice} corrente: quest'ultimo può assumere valori compresi fra
+\const{PRIO\_MIN} e \const{PRIO\_MAX}; nel caso di Linux sono fra $-20$ e
+$19$,\footnote{in realtà l'intervallo varia a seconda delle versioni di
+ kernel, ed è questo a partire dal kernel 1.3.43, anche se oggi si può avere
+ anche l'intervallo fra $-20$ 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à, valori negativi
+comportano invece un aumento della priorità. Con i kernel precedenti il
+2.6.12 solo l'amministratore\footnote{o un processo con la
+ \itindex{capabilities} \textit{capability} \const{CAP\_SYS\_NICE}, vedi
+ sez.~\ref{sec:proc_capabilities}.} può specificare valori negativi
+di \param{inc} che permettono di aumentare la priorità di un processo, a
+partire da questa versione è consentito anche agli utenti normali alzare
+(entro certi limiti, che vedremo più avanti) la priorità dei propri processi.
+
+Gli standard SUSv2 e POSIX.1 prevedono che la funzione ritorni il nuovo valore
+di \var{nice} del processo; tuttavia la system call di Linux non segue questa
+convenzione e restituisce sempre 0 in caso di successo e $-1$ in caso di
+errore; questo perché $-1$ è un valore di \var{nice} legittimo e questo
+comporta una confusione con una eventuale condizione di errore. La system call
+originaria inoltre non consente, se non dotati di adeguati privilegi, di
+diminuire un valore di \var{nice} precedentemente innalzato.
+
+Fino alle \acr{glibc} 2.2.4 la funzione di libreria riportava direttamente il
+risultato dalla system call, violando lo standard, per cui per ottenere il
+nuovo valore occorreva una successiva chiamata alla funzione
+\func{getpriority}. A partire dalla \acr{glibc} 2.2.4 \func{nice} è stata
+reimplementata e non viene più chiamata la omonima system call, con questa
+versione viene restituito come valore di ritorno il valore di \var{nice}, come
+richiesto dallo standard.\footnote{questo viene fatto chiamando al suo interno
+ \func{setpriority}, che tratteremo a breve.} In questo caso l'unico modo
+per rilevare in maniera affidabile una condizione di errore è quello di
+azzerare \var{errno} prima della chiamata della funzione e verificarne il
+valore quando \func{nice} restituisce $-1$.
+
+Per leggere il valore di \textit{nice} di un processo occorre usare la
+funzione \funcd{getpriority}, derivata da BSD; il suo 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[\errcode{ESRCH}] non c'è nessun processo che corrisponda ai valori di
+ \param{which} e \param{who}.
+ \item[\errcode{EINVAL}] il valore di \param{which} non è valido.
+ \end{errlist}}
+\end{prototype}
+\noindent nelle 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, a seconda del valore di \param{which}, di leggere la
+priorità di un processo, di un gruppo di processi (vedi
+sez.~\ref{sec:sess_proc_group}) o di un utente, specificando un corrispondente
+valore per \param{who} secondo la legenda di tab.~\ref{tab:proc_getpriority};
+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
+ \const{PRIO\_PROCESS} & \type{pid\_t} & processo \\
+ \const{PRIO\_PRGR} & \type{pid\_t} & \itindex{process~group}
+ \textit{process group} \\
+ \const{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}