Altra roba, res_query.
[gapil.git] / prochand.tex
index 5fe5845314eab353f3866216f577efe4110fc74a..177155d436192e9a36ea0584c709041277243a59 100644 (file)
@@ -1,6 +1,6 @@
 %% prochand.tex
 %%
-%% Copyright (C) 2000-2002 Simone Piccardi.  Permission is granted to
+%% Copyright (C) 2000-2004 Simone Piccardi.  Permission is granted to
 %% copy, distribute and/or modify this document under the terms of the GNU Free
 %% Documentation License, Version 1.1 or any later version published by the
 %% Free Software Foundation; with the Invariant Sections being "Prefazione",
@@ -126,13 +126,14 @@ struttura, alla cui base c'
 processi.
 
 Il kernel mantiene una tabella dei processi attivi, la cosiddetta
-\textit{process table}; per ciascun processo viene mantenuta una voce nella
-tabella dei processi costituita da una struttura \struct{task\_struct}, che
-contiene tutte le informazioni rilevanti per quel processo. Tutte le strutture
-usate a questo scopo sono dichiarate nell'header file \file{linux/sched.h}, ed
-uno schema semplificato, che riporta la struttura delle principali informazioni
-contenute nella \struct{task\_struct} (che in seguito incontreremo a più
-riprese), è mostrato in \figref{fig:proc_task_struct}.
+\textit{process table}; per ciascun processo viene mantenuta una voce,
+costituita da una struttura \struct{task\_struct}, nella tabella dei processi
+che contiene tutte le informazioni rilevanti per quel processo. Tutte le
+strutture usate a questo scopo sono dichiarate nell'header file
+\file{linux/sched.h}, ed uno schema semplificato, che riporta la struttura
+delle principali informazioni contenute nella \struct{task\_struct} (che in
+seguito incontreremo a più riprese), è mostrato in
+\figref{fig:proc_task_struct}.
 
 \begin{figure}[htb]
   \centering
@@ -142,7 +143,6 @@ riprese), 
   \label{fig:proc_task_struct}
 \end{figure}
 
-
 Come accennato in \secref{sec:intro_unix_struct} è lo
 \textit{scheduler}\index{scheduler} che decide quale processo mettere in
 esecuzione; esso viene eseguito ad ogni system call ed ad ogni
@@ -166,13 +166,12 @@ esecuzione fino alla successiva invocazione.
 \subsection{Una panoramica sulle funzioni fondamentali}
 \label{sec:proc_handling_intro}
 
-I processi vengono creati dalla funzione \func{fork}; in molti unix questa è
-una system call, Linux però usa un'altra nomenclatura, e la funzione
-\func{fork} è basata a sua volta sulla system call \func{\_\_clone}, che viene
-usata anche per generare i \textit{thread}.  Il processo figlio creato dalla
-\func{fork} è una copia identica del processo processo padre, ma ha un nuovo
-\acr{pid} e viene eseguito in maniera indipendente (le differenze fra padre e
-figlio sono affrontate in dettaglio in \secref{sec:proc_fork}).
+In un sistema unix-like i processi vengono sempre creati da altri processi
+tramite la funzione \func{fork}; il nuovo processo (che viene chiamato
+\textsl{figlio}) creato dalla \func{fork} è una copia identica del processo
+processo originale (detto \textsl{padre}), ma ha un nuovo \acr{pid} e viene
+eseguito in maniera indipendente (le differenze fra padre e figlio sono
+affrontate in dettaglio in \secref{sec:proc_fork}).
 
 Se si vuole che il processo padre si fermi fino alla conclusione del processo
 figlio questo deve essere specificato subito dopo la \func{fork} chiamando la
@@ -263,7 +262,7 @@ prototipi sono:
 \bodydesc{Entrambe le funzioni non riportano condizioni di errore.}
 \end{functions}
 \noindent esempi dell'uso di queste funzioni sono riportati in
-\figref{fig:proc_fork_code}, nel programma di esempio \file{ForkTest.c}.
+\figref{fig:proc_fork_code}, nel programma \file{ForkTest.c}.
 
 Il fatto che il \acr{pid} sia un numero univoco per il sistema lo rende un
 candidato per generare ulteriori indicatori associati al processo di cui
@@ -349,53 +348,11 @@ sempre un solo padre (il cui \acr{pid} pu
 che non è il \acr{pid} di nessun processo.
 
 \begin{figure}[!htb]
-  \footnotesize
-  \begin{lstlisting}{}
-#include <errno.h>       /* error definitions and routines */ 
-#include <stdlib.h>      /* C standard library */
-#include <unistd.h>      /* unix standard library */
-#include <stdio.h>       /* standard I/O library */
-#include <string.h>      /* string functions */
-
-/* Help printing routine */
-void usage(void);
-
-int main(int argc, char *argv[])
-{
-/* 
- * Variables definition  
- */
-    int nchild, i;
-    pid_t pid;
-    int wait_child  = 0;
-    int wait_parent = 0;
-    int wait_end    = 0;
-    ...        /* handling options */
-    nchild = atoi(argv[optind]);
-    printf("Test for forking %d child\n", nchild);
-    /* loop to fork children */
-    for (i=0; i<nchild; i++) {
-        if ( (pid = fork()) < 0) { 
-            /* on error exit */ 
-            printf("Error on %d child creation, %s\n", i+1, strerror(errno));
-            exit(-1); 
-        }
-        if (pid == 0) {   /* child */
-            printf("Child %d successfully executing\n", ++i);
-            if (wait_child) sleep(wait_child);
-            printf("Child %d, parent %d, exiting\n", i, getppid());
-            exit(0);
-        } else {          /* parent */
-            printf("Spawned %d child, pid %d \n", i+1, pid);
-            if (wait_parent) sleep(wait_parent);
-            printf("Go to next child \n");
-        }
-    }
-    /* normal exit */
-    if (wait_end) sleep(wait_end);
-    return 0;
-}
-  \end{lstlisting}
+  \footnotesize \centering
+  \begin{minipage}[c]{15cm}
+  \includecodesample{listati/ForkTest.c}
+  \end{minipage}
+  \normalsize
   \caption{Esempio di codice per la creazione di nuovi processi.}
   \label{fig:proc_fork_code}
 \end{figure}
@@ -582,11 +539,11 @@ i processi figli.
 
 Quello che succede è che quando lo standard output del padre viene rediretto,
 lo stesso avviene anche per tutti i figli; la funzione \func{fork} infatti ha
-la caratteristica di duplicare (allo stesso modo in cui lo fa la funzione
-\func{dup}, trattata in \secref{sec:file_dup}) nei figli tutti i file
-descriptor aperti nel padre, il che comporta che padre e figli condividono le
+la caratteristica di duplicare nei figli tutti i file descriptor aperti nel
+padre (allo stesso modo in cui lo fa la funzione \func{dup}, trattata in
+\secref{sec:file_dup}), il che comporta che padre e figli condividono le
 stesse voci della \textit{file table} (per la spiegazione di questi termini si
-veda \secref{sec:file_sharing}) fra cui c'è anche la posizione corrente nel
+veda \secref{sec:file_sharing}) fra cui c'è anche la posizione corrente nel
 file.
 
 In questo modo se un processo scrive sul file aggiornerà la posizione corrente
@@ -1171,9 +1128,7 @@ questo vettore \emph{deve} essere terminato da un puntatore nullo.
 
 Nel secondo caso le stringhe degli argomenti sono passate alla funzione come
 lista di puntatori, nella forma:
-\begin{lstlisting}[labelstep=0,frame=,indent=1cm]{}
-  char *arg0, char *arg1,  ..., char *argn, NULL
-\end{lstlisting}
+\includecodesnip{listati/char_list.c}
 che deve essere terminata da un puntatore nullo.  In entrambi i casi vale la
 convenzione che il primo argomento (\var{arg0} o \var{argv[0]}) viene usato
 per indicare il nome del file che contiene il programma che verrà eseguito.
@@ -1225,7 +1180,7 @@ indicato dall'argomento \param{path}, che viene interpretato come il
 
 \begin{figure}[htb]
   \centering
-  \includegraphics[width=15cm]{img/exec_rel}
+  \includegraphics[width=16cm]{img/exec_rel}
   \caption{La interrelazione fra le sei funzioni della famiglia \func{exec}.}
   \label{fig:proc_exec_relat}
 \end{figure}
@@ -1780,13 +1735,16 @@ coincide con uno dei di quelli del gruppo \textit{real}, \textit{effective} o
 \label{sec:proc_setgroups}
 
 Le ultime funzioni che esamineremo sono quelle che permettono di operare sui
-gruppi supplementari. Ogni processo può avere fino a \const{NGROUPS\_MAX}
-gruppi supplementari in aggiunta al gruppo primario, questi vengono ereditati
-dal processo padre e possono essere cambiati con queste funzioni.
-
-La funzione che permette di leggere i gruppi supplementari è
-\funcd{getgroups}; questa funzione è definita nello standard POSIX ed il suo
-prototipo è:
+gruppi supplementari cui un utente può appartenere. Ogni processo può avere
+almeno \const{NGROUPS\_MAX} gruppi supplementari\footnote{il numero massimo di
+  gruppi secondari può essere ottenuto con \func{sysconf} (vedi
+  \secref{sec:sys_sysconf}), leggendo il parametro
+  \texttt{\_SC\_NGROUPS\_MAX}.} in aggiunta al gruppo primario; questi vengono
+ereditati dal processo padre e possono essere cambiati con queste funzioni.
+
+La funzione che permette di leggere i gruppi supplementari associati ad un
+processo è \funcd{getgroups}; questa funzione è definita nello standard
+POSIX.1, ed il suo prototipo è:
 \begin{functions}
   \headdecl{sys/types.h}
   \headdecl{unistd.h}
@@ -1885,6 +1843,19 @@ compila con il flag \cmd{-ansi}, 
 scrivere codice portabile.
 
 
+%
+% Da fare !!!
+% insieme alla risistemazioni dei titoli delle sezioni precedenti
+% (accorpare il materiale) qualosa tipo:
+% le funzioni di controllo
+% estenzioni di Linux
+%
+%\subsection{La gestione delle capabilities}
+%\label{sec:proc_capabilities}
+
+
+
+
 \section{La gestione della priorità di esecuzione}
 \label{sec:proc_priority}
 
@@ -2042,13 +2013,13 @@ 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\index{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
+Durante la sua esecuzione lo scheduler\index{scheduler} scandisce la coda dei
+processi in stato \textit{runnable} associando, in base al valore di
+\var{counter}, un peso ad ogni 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
+  multiprocessore viene favorito un processo 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
@@ -2101,15 +2072,16 @@ Restituisce il valore di \var{nice} per l'insieme dei processi specificati.
   \item[\errcode{EINVAL}] il valore di \param{which} non è valido.
   \end{errlist}}
 \end{prototype}
-\noindent (in vecchie versioni può essere necessario includere anche
+\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à).
+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.
+La funzione permette, a seconda del valore di \param{which}, di leggere la
+priorità di un processo, di un gruppo di processi (vedi
+\secref{sec:sess_proc_group}) o di un utente, specificando un corrispondente
+valore per \param{who} secondo la legenda di \tabref{tab:proc_getpriority}; un
+valore nullo di quest'ultimo indica il processo, il gruppo di processi o
+l'utente correnti.
 
 \begin{table}[htb]
   \centering
@@ -2177,7 +2149,7 @@ processo qualsiasi sia la sua priorit
   siano installate le patch di RTLinux, RTAI o Adeos, con i quali è possibile
   ottenere un sistema effettivamente hard real-time. In tal caso infatti gli
   interrupt vengono intercettati dall'interfaccia real-time (o nel caso di
-  Adeos gestiti dalle code del nano-kernel), in modo da poterlo controllare
+  Adeos gestiti dalle code del nano-kernel), in modo da poterli controllare
   direttamente qualora ci sia la necessità di avere un processo con priorità
   più elevata di un \textit{interrupt handler}.} mentre con l'incorrere in un
 page fault\index{page fault} si possono avere ritardi non previsti. Se
@@ -2186,24 +2158,23 @@ controllo della memoria virtuale (vedi \secref{sec:proc_mem_lock}), il primo
 non è superabile e può comportare ritardi non prevedibili riguardo ai tempi di
 esecuzione di qualunque processo.
 
-In ogni caso occorre usare le priorità assolute con molta attenzione: se si dà
-ad un processo una priorità assoluta e questo finisce in un loop infinito,
-nessun altro processo potrà essere eseguito, ed esso sarà mantenuto in
-esecuzione permanentemente assorbendo tutta la CPU e senza nessuna possibilità
-di riottenere l'accesso al sistema. Per questo motivo è sempre opportuno,
-quando si lavora con processi che usano priorità assolute, tenere attiva una
-shell cui si sia assegnata la massima priorità assoluta, in modo da poter
-essere comunque in grado di rientrare nel sistema.
+Occorre usare le priorità assolute con molta attenzione: se si dà ad un
+processo una priorità assoluta e questo finisce in un loop infinito, nessun
+altro processo potrà essere eseguito, ed esso sarà mantenuto in esecuzione
+permanentemente assorbendo tutta la CPU e senza nessuna possibilità di
+riottenere l'accesso al sistema. Per questo motivo è sempre opportuno, quando
+si lavora con processi che usano priorità assolute, tenere attiva una shell
+cui si sia assegnata la massima priorità assoluta, in modo da poter essere
+comunque in grado di rientrare nel sistema.
 
 Quando c'è un processo con priorità assoluta lo scheduler\index{scheduler} lo
 metterà in esecuzione prima di ogni processo normale. In caso di più processi
 sarà eseguito per primo quello con priorità assoluta più alta. Quando ci sono
 più processi con la stessa priorità assoluta questi vengono tenuti in una coda
 e tocca al kernel decidere quale deve essere eseguito.
-
 Il meccanismo con cui vengono gestiti questi processi dipende dalla politica
 di scheduling che si è scelto; lo standard ne prevede due:
-\begin{basedescript}{\desclabelwidth{2cm}\desclabelstyle{\nextlinelabel}}
+\begin{basedescript}{\desclabelwidth{1.2cm}\desclabelstyle{\nextlinelabel}}
 \item[\textit{FIFO}] \textit{First In First Out}. Il processo viene eseguito
   fintanto che non cede volontariamente la CPU, si blocca, finisce o viene
   interrotto da un processo a priorità più alta.
@@ -2227,18 +2198,17 @@ prototipo 
     \item[\errcode{EINVAL}] il valore di \param{policy} non esiste o il
       relativo valore di \param{p} non è valido.
     \item[\errcode{EPERM}] il processo non ha i privilegi per attivare la
-      politica richiesta (vale solo per \const{SCHED\_FIFO} e
-      \const{SCHED\_RR}).
+      politica richiesta.
   \end{errlist}}
 \end{prototype}
 
 La funzione esegue l'impostazione per il processo specificato dall'argomento
 \param{pid}; un valore nullo esegue l'impostazione per il processo corrente.
-Solo un processo con i privilegi di amministratore può impostare delle
-priorità assolute diverse da zero. La politica di scheduling è specificata
-dall'argomento \param{policy} i cui possibili valori sono riportati in
-\tabref{tab:proc_sched_policy}; un valore negativo per \param{policy} mantiene
-la politica di scheduling corrente.
+La politica di scheduling è specificata dall'argomento \param{policy} i cui
+possibili valori sono riportati in \tabref{tab:proc_sched_policy}; un valore
+negativo per \param{policy} mantiene la politica di scheduling corrente.
+Solo un processo con i privilegi di amministratore può impostare priorità
+assolute diverse da zero o politiche \const{SCHED\_FIFO} e \const{SCHED\_RR}.
 
 \begin{table}[htb]
   \centering
@@ -2266,14 +2236,10 @@ priorit
 massimo ed uno minimo, che nel caso sono rispettivamente 1 e 99 (il valore
 zero è legale, ma indica i processi normali).
 
-\begin{figure}[!htb]
+\begin{figure}[!bht]
   \footnotesize \centering
   \begin{minipage}[c]{15cm}
-    \begin{lstlisting}[labelstep=0]{}%,frame=,indent=1cm]{}
-struct sched_param {
-    int sched_priority;
-};
-    \end{lstlisting}
+    \includestruct{listati/sched_param.c}
   \end{minipage} 
   \normalsize 
   \caption{La struttura \structd{sched\_param}.} 
@@ -2297,7 +2263,7 @@ e \funcd{sched\_get\_priority\_min}, i cui prototipi sono:
   \bodydesc{La funzioni ritornano il valore della priorità in caso di successo
     e -1 in caso di errore, nel qual caso \var{errno} può assumere i valori:
     \begin{errlist}
-    \item[\errcode{EINVAL}] il valore di \param{policy} è invalido.
+    \item[\errcode{EINVAL}] il valore di \param{policy} non è valido.
   \end{errlist}}
 \end{functions}
 
@@ -2346,7 +2312,6 @@ prototipi sono:
   \funcdecl{int sched\_setparam(pid\_t pid, const struct sched\_param *p)}
   Imposta la priorità assoluta del processo \param{pid}.
 
-
   \funcdecl{int sched\_getparam(pid\_t pid, struct sched\_param *p)}
   Legge la priorità assoluta del processo \param{pid}.