\begin{figure}[htb]
\centering
- \includegraphics[width=13cm]{img/task_struct}
+ \includegraphics[width=11cm]{img/task_struct}
\caption{Schema semplificato dell'architettura delle strutture usate dal
kernel nella gestione dei processi.}
\label{fig:proc_task_struct}
di altre occasioni.}
% TODO completare questa parte su quando viene chiamato lo scheduler.
(ma può essere anche attivato esplicitamente). Il timer di sistema provvede
-comunque a che esso sia invocato periodicamente, generando un interrupt
-periodico secondo la frequenza specificata dalla costante \const{HZ}, definita
-in \file{asm/param.h}, ed il cui valore è espresso in Hertz.\footnote{Fino al
- kernel 2.4 il valore usuale di questa costante era 100, per tutte le
- architetture eccetto l'alpha, per la quale era 1000. Occorre fare attenzione
- a non confondere questo valore con quello dei clock tick (vedi
- sez.~\ref{sec:sys_unix_time}).}
-% TODO verificare gli ultimi cambiamenti del 2.6
-% Si ha cioè un interrupt dal timer ogni centesimo di secondo.
+comunque a che esso sia invocato periodicamente; generando un interrupt
+periodico secondo la frequenza specificata dalla costante
+\const{HZ},\footnote{fino al kernel 2.4 il valore usuale di questa costante
+ era 100, per tutte le architetture eccetto l'alpha, per la quale era 1000,
+ nel 2.6 è stato portato a 1000 su tutte le architetture; occorre fare
+ attenzione a non confondere questo valore con quello dei clock tick (vedi
+ sez.~\ref{sec:sys_unix_time}).} definita in \file{asm/param.h}, ed il cui
+valore è espresso in Hertz.\footnote{a partire dal kernel 2.6.21 è stato
+ introdotto (a cura di Ingo Molnar) un meccanismo completamente diverso,
+ detto \textit{tickless}, in cui non c'è più una interruzione periodica con
+ frequenza prefissata, ma ad ogni chiamata del time viene programmata
+ l'interruzione successiva sulla base di una stima; in questo modo si evita
+ di dover eseguire un migliaio di interruzioni al secondo anche su macchine
+ che non stanno facendo nulla, con un forte risparmio nell'uso dell'energia
+ da parte del processore che può essere messo in stato di sospensione anche
+ per lunghi periodi di tempo.}
+
Ogni volta che viene eseguito, lo \itindex{scheduler} \textit{scheduler}
effettua il calcolo delle priorità dei vari processi attivi (torneremo su
affrontato in dettaglio in sez.~\ref{sec:proc_perms}.
-\subsection{La funzione \func{fork}}
+\subsection{La funzione \func{fork} e le funzioni di creazione dei processi}
\label{sec:proc_fork}
La funzione \funcd{fork} è la funzione fondamentale della gestione dei
sez.~\ref{sec:ipc_sysv_shm});
\item i limiti sulle risorse (vedi sez.~\ref{sec:sys_resource_limit});
\item le priorità real-time e le affinità di processore (vedi
- sez.~\ref{sec:proc_real_time});
+ sez.~\ref{sec:proc_real_time} e sez.\ref{sec:proc_sched_multiprocess});
\item le variabili di ambiente (vedi sez.~\ref{sec:proc_environ}).
\end{itemize*}
Le differenze fra padre e figlio dopo la \func{fork} invece sono:
\end{itemize*}
-\subsection{La funzione \func{vfork}}
-\label{sec:proc_vfork}
-
-La funzione \func{vfork} è esattamente identica a \func{fork} ed ha la stessa
+Una seconda funzione storica usata per la creazione di un nuovo processo è
+\func{vfork}, che è esattamente identica a \func{fork} ed ha la stessa
semantica e gli stessi errori; la sola differenza è che non viene creata la
tabella delle pagine né la struttura dei task per il nuovo processo. Il
processo padre è posto in attesa fintanto che il figlio non ha eseguito una
\funcd{waitpid} che effettua lo stesso servizio, ma dispone di una serie di
funzionalità più ampie, legate anche al controllo di sessione (si veda
sez.~\ref{sec:sess_job_control}). Dato che è possibile ottenere lo stesso
-comportamento di \func{wait} si consiglia di utilizzare sempre questa
-funzione, il cui prototipo è:
+comportamento di \func{wait}\footnote{in effetti eseguire il codice
+ \code{wait(\&s)} è del tutto equivalente a \code{waitpid(WAIT\_ANY}, \&s,
+ 0)}. } si consiglia di utilizzare sempre questa funzione, il cui prototipo
+è:
\begin{functions}
\headdecl{sys/types.h}
\headdecl{sys/wait.h}
\footnotesize
\begin{tabular}[c]{|c|c|p{8cm}|}
\hline
- \textbf{Valore} & \textbf{Opzione} &\textbf{Significato}\\
+ \textbf{Valore} & \textbf{Costante} &\textbf{Significato}\\
\hline
\hline
$<-1$& -- & attende per un figlio il cui
\file{signal.h} ed elencate in tab.~\ref{tab:sig_signal_list}, e stampato
usando le apposite funzioni trattate in sez.~\ref{sec:sig_strsignal}.
-
-\subsection{Le funzioni \func{wait3} e \func{wait4}}
-\label{sec:proc_wait4}
-
Linux, seguendo un'estensione di BSD, supporta altre due funzioni per la
lettura dello stato di terminazione di un processo, analoghe alle precedenti
ma che prevedono un ulteriore argomento attraverso il quale il kernel può
in modalità \textit{fifo}, per permettere l'esecuzione degli altri processi
con pari priorità quando la sezione più urgente è finita.
+
+\subsection{Il controllo dello \textit{scheduler} per i sistemi multiprocessore}
+\label{sec:proc_sched_multiprocess}
+
Infine con il supporto dei sistemi multiprocessore sono state introdotte delle
funzioni che permettono di controllare in maniera più dettagliata la scelta di
quale processore utilizzare per eseguire un certo programma. Uno dei problemi
-che si pongono nei sistemi multiprocessore è infatti quello
-\index{effetto~ping-pong} dell'\textsl{effetto ping-pong}. Può accadere cioè
-che lo scheduler, quando riavvia un processo precedentemente interrotto,
-scegliendo il primo processore disponibile lo faccia eseguire da un processore
-diverso rispetto a quello su cui era stato eseguito in precedenza. Se il
-processo passa da un processore all'altro in questo modo (cosa che avveniva
-abbastanza di frequente con i kernel della seria 2.4.x) si ha
-l'\textsl{effetto ping-pong}.
+che si pongono nei sistemi multiprocessore è infatti quello del cosiddetto
+\index{effetto~ping-pong} \textsl{effetto ping-pong}. Può accadere cioè che lo
+scheduler, quando riavvia un processo precedentemente interrotto scegliendo il
+primo processore disponibile, lo faccia eseguire da un processore diverso
+rispetto a quello su cui era stato eseguito in precedenza. Se il processo
+passa da un processore all'altro in questo modo (cosa che avveniva abbastanza
+di frequente con i kernel della seria 2.4.x) si ha l'\textsl{effetto
+ ping-pong}.
Questo tipo di comportamento può generare dei seri problemi di prestazioni;
infatti tutti i processori moderni utilizzano una memoria interna (la
\itindbeg{CPU~affinity}
Per ovviare a questo tipo di problemi è nato il concetto di \textsl{affinità
- di processore} (o \textit{CPU affinity}); la
-possibilità cioè di far sì che un processo possa essere assegnato per
-l'esecuzione sempre allo stesso processore. Lo scheduler dei kernel della
-serie 2.4.x aveva una scarsa \textit{CPU affinity}, e
-\index{effetto~ping-pong} l'effetto ping-pong era comune; con il nuovo
-scheduler dei kernel della 2.6.x questo problema è stato risolto ed esso cerca
-di mantenere il più possibile ciascun processo sullo stesso processore.
+ di processore} (o \textit{CPU affinity}); la possibilità cioè di far sì che
+un processo possa essere assegnato per l'esecuzione sempre allo stesso
+processore. Lo scheduler dei kernel della serie 2.4.x aveva una scarsa
+\textit{CPU affinity}, e \index{effetto~ping-pong} l'effetto ping-pong era
+comune; con il nuovo scheduler dei kernel della 2.6.x questo problema è stato
+risolto ed esso cerca di mantenere il più possibile ciascun processo sullo
+stesso processore.
In certi casi però resta l'esigenza di poter essere sicuri che un processo sia
sempre eseguito dallo stesso processore,\footnote{quella che viene detta