09e67032993948e4907a973ea79df3e9ceb82f9d
[gapil.git] / process.tex
1 \chapter{I processi}
2 \label{cha:process}
3
4 Come accennato nell'introduzione in un sistema unix ogni attività del sistema
5 viene svolta tramite i processi. Questo significa che quando un programma
6 viene posto in esecuzione, viene fatto partire un processo che si incarica di
7 eseguirne il codice. In sostanza i processi costituiscono l'unità base per
8 l'allocazione e l'uso delle risorse del sistema.
9
10 Una delle caratteristiche essenziali di unix (che esamineremo in dettaglio più
11 avanti) è che ogni processo può a sua volta generare altri processi figli
12 (\textit{child}): questo è ad esempio quello che fa la shell quando mette in
13 esecuzione il programma che gli indichiamo nella linea di comando.
14
15 Una seconda caratteristica è che ogni processo viene sempre generato in tale
16 modo da un processo genitore (\textit{parent}) attraverso una apposita system
17 call. Questo vale per tutti i processi, tranne per un processo speciale, che
18 normalmente è \texttt{/sbin/init}, che invece viene lanciato dal kernel finita
19 la fase di avvio e che quindi non è figlio di nessuno.
20
21 Tutto ciò significa che, come per i file su disco, i processi sono organizzati
22 gerarchicamente dalla relazione fra genitori e figli; alla base dell'albero in
23 questo caso c'è init che è progenitore di ogni altro processo.
24
25
26 \section{Una panoramica sui concetti base}
27 \label{sec:proc_gen}
28
29 Ogni processo viene identificato dal sistema da un numero identificativo
30 unico, il \textit{process id} o \textit{pid}. Questo viene assegnato in forma
31 progressiva ogni volta che un nuovo processo viene creato, fino ad un limite
32 massimo (in genere essendo detto numero memorizzato in un intero a 16 bit si
33 arriva a 32767) oltre il quale si riparte dal numero più basso disponibile
34 (FIXME: verificare, non sono sicuro).  Per questo motivo processo il processo
35 di avvio (init) ha sempre il pid uguale a uno.
36
37 Quando un processo ha concluso il suo compito o ha incontrato un errore non
38 risolvibile esso può essere terminato con la funzione \texttt{exit} (la
39 questione è più complessa ma ci torneremo più avanti). La vita del processo
40 però termina solo quando viene chiamata la quando la sua conclusione viene
41 ricevuta dal processo padre, a quel punto tutte le risorse allocate nel
42 sistema ad esso associate vengono rilasciate.
43
44 I processi vengono creati dalla funzione \texttt{fork}; in genere questa è una
45 system call, Linux però usa un'altra nomenclatura, e la funzione fork è basata
46 a sua volta sulla system call \texttt{clone}, che viene usata anche per
47 generare i \textit{thread}.  Il processo figlio creato dalla \textit{fork} è
48 una copia identica del processo processo padre, solo che ha un suo pid proprio.
49
50 Dopo l'esecuzione di una fork sia il processo padre che il processo figlio
51 continuano ad essere eseguiti normalmente, ed il processo figlio esegue
52 esattamente lo stesso codice del padre. La sola differenza è che nel processo
53 padre il valore di ritorno della funzione fork è il pid del processo figlio,
54 mentre nel figlio è zero; in questo modo il programma può identificare se
55 viene eseguito dal padre o dal figlio. 
56
57 Se si vuole che il processo padre si fermi fino alla conclusione del processo
58 figlio questo deve essere specificato subito dopo la fork chiamando la
59 funzione \texttt{wait} o la funzione \texttt{waitpid}, che restituiscono anche
60 una informazione abbastanza limitata (il codice di uscita) sulle cause della
61 terminazione del processo.
62
63 Avere due processi che eseguono esattamente lo stesso codice non è molto
64 utile, mormalmente si genera un secondo processo per affidagli l'esecuzione di
65 un compito specifico (ad esempio gestire una connessione dopo che questa è
66 stata stabilita), o fargli eseguire (come fa la shell) un altro programma. Per
67 questo si usa la seconda funzione fondamentale per programmazione coi processi
68 che è la \texttt{exec}.
69
70 Il programma che un processo sta eseguendo si chiama immagine del processo
71 (\textit{process image}), le funzioni della famiglia \textit{exec} permette di
72 caricare un'altro programma da disco sostituendo quest'ultimo alla process
73 image corrente, questo fa si che la precedente immagine venga completamente
74 cancellata e quando il nuovo programma esce anche il processo termina, senza
75 ritornare alla precedente immagine.
76
77 Per questo motivo la \texttt{fork} e la \texttt{exec} sono funzioni molto
78 particolari con caratteristiche uniche rispetto a tutte le altre, infatti la
79 prima ritorna due volte (nel processo padre e nel figlio) mentre la seconda
80 non ritorna mai (in quanto viene eseguito un altro programma).
81
82
83 \section{Identificazione}
84 \label{sec:proc_id}
85
86 Come detto ogni processo è identificato univocamente dal sistema per il suo
87 pid; quest'ultimo è un apposito tipo di dato, il \texttt{pid\_t} che in
88 genere è un intero con segno (nel caso di Linux e delle glibc il tipo usato è
89 \texttt{int}.
90
91 Tutti i processi inoltre portano traccia del pid del genitore, chiamato in
92 genere \textit{ppid} (da \textit{Parente Process Id}). Questi identificativi
93 possono essere ottenuti da un programma usando le funzioni:
94 \begin{itemize} 
95   \item \texttt{pid\_t getpid(void)} restituisce il pid del processo corrente.
96     
97   \item \texttt{pid\_t getppid(void)} restituisce il pid del padre del processo
98     corrente.
99
100 \end{itemize}
101 (per l'accesso a queste funzioni e ai relativi tipi di dati occorre includere
102 gli header files \texttt{unistd.h} e \texttt{sys/types.h}. 
103
104
105 \section{Provilegi e permessi}
106 \label{sec:process_perms}
107
108 Va messo qui tutta la storia su effective, real, saved uid, e pure le cose di
109 linux come il filesystem uid.
110
111
112
113 \section{Creazione dei processi}
114 \label{sec:proc_fork}