X-Git-Url: https://gapil.gnulinux.it/gitweb/?p=gapil.git;a=blobdiff_plain;f=prochand.tex;h=3b40d63c067da2a040a08f67c9b246d53227329b;hp=72fcc78465a6c5d57d9da2b07afbaf38adfe4245;hb=ffde006b4b38517dd190c394b769c619d13174a5;hpb=68f626be4f8d5c0816b9b552f744f05f0d72c8dc diff --git a/prochand.tex b/prochand.tex index 72fcc78..3b40d63 100644 --- a/prochand.tex +++ b/prochand.tex @@ -11,63 +11,73 @@ dei processi, della gestione dei loro attributi e privilegi, e di tutte le funzioni a questo connesse. -\section{Una panoramica sui concetti base} -\label{sec:prochand_gen} +\section{Introduzione} +\label{sec:proc_gen} + +Partiremo con una introduzione generale ai concetti che stanno alla base della +gestione dei processi in unix. Introdurremo in questa sezione l'architettura +della gestione dei processi e le sue principali caratteristiche. + +\subsection{La gerarchia dei processi} +\label{sec:proc_hierarchy} Una delle caratteristiche essenziali di unix (che esamineremo in dettaglio più avanti) è che ogni processo può a sua volta generare altri processi figli (\textit{child}): questo è ad esempio quello che fa la shell quando mette in esecuzione il programma che gli indichiamo nella linea di comando. -Una seconda caratteristica è che ogni processo viene sempre generato in tale -modo da un processo genitore (\textit{parent}) attraverso una apposita system -call. Questo vale per tutti i processi, tranne per un processo speciale, che -normalmente è \texttt{/sbin/init}, che invece viene lanciato dal kernel finita -la fase di avvio e che quindi non è figlio di nessuno. +Una seconda caratteristica di unix è che ogni processo viene sempre generato +in tale modo da un processo genitore (\textit{parent}) attraverso una apposita +system call. Questo vale per tutti i processi, tranne per un processo +speciale, che normalmente è \file{/sbin/init}, che invece viene lanciato dal +kernel finita la fase di avvio e che quindi non è figlio di nessuno. Tutto ciò significa che, come per i file su disco, i processi sono organizzati gerarchicamente dalla relazione fra genitori e figli; alla base dell'albero in -questo caso c'è init che è progenitore di ogni altro processo. - +questo caso c'è \file{init} che è progenitore di ogni altro processo. -\section{Gli identificatori dei processi} -\label{sec:prochand_id} -Ogni processo viene identificato dal sistema da un numero identificativo -unico, il \textit{process id} o \textit{pid}. Questo viene assegnato in forma -progressiva ogni volta che un nuovo processo viene creato, fino ad un limite -massimo (in genere essendo detto numero memorizzato in un intero a 16 bit si -arriva a 32767) oltre il quale si riparte dal numero più basso disponibile -(FIXME: verificare, non sono sicuro). Per questo motivo processo il processo -di avvio (init) ha sempre il pid uguale a uno. +\subsection{La gestione dei processi} +\label{sec:proc_handling_intro} -Ogni processo è identificato univocamente dal sistema per il suo pid; -quest'ultimo è un tipo di dato standard, il \texttt{pid\_t} che in genere è un -intero con segno (nel caso di Linux e delle glibc il tipo usato è -\texttt{int}. +I processi vengono creati dalla funzione \texttt{fork}; in genere questa è una +system call, ma Linux però usa un'altra nomenclatura, e la funzione fork è +basata a sua volta sulla system call \texttt{clone}, che viene usata anche per +generare i \textit{thread}. Il processo figlio creato dalla \textit{fork} è +una copia identica del processo processo padre, solo che ha un suo pid +proprio. -Tutti i processi inoltre portano traccia del pid del genitore, chiamato in -genere \textit{ppid} (da \textit{Parente Process Id}). Questi identificativi -possono essere ottenuti da un programma usando le funzioni: -\begin{functions} -\headdecl{sys/types.h} -\headdecl{unistd.h} -\funcdecl{pid\_t getpid(void)} restituisce il pid del processo corrente. -\funcdecl{pid\_t getppid(void)} restituisce il pid del padre del processo - corrente. -\end{functions} +Se si vuole che il processo padre si fermi fino alla conclusione del processo +figlio questo deve essere specificato subito dopo la fork chiamando la +funzione \texttt{wait} o la funzione \texttt{waitpid}, che restituiscono anche +una informazione abbastanza limitata (il codice di uscita) sulle cause della +terminazione del processo. +Quando un processo ha concluso il suo compito o ha incontrato un errore non +risolvibile esso può essere terminato con la funzione \texttt{exit} (si veda +quanto discusso in \secref{sec:proc_termination}). La vita del processo +però termina solo quando viene chiamata la quando la sua conclusione viene +ricevuta dal processo padre, a quel punto tutte le risorse allocate nel +sistema ad esso associate vengono rilasciate. -\section{Il controllo dei processi} -\label{sec:prochand_control} +Avere due processi che eseguono esattamente lo stesso codice non è molto +utile, normalmente si genera un secondo processo per affidargli l'esecuzione di +un compito specifico (ad esempio gestire una connessione dopo che questa è +stata stabilita), o fargli eseguire (come fa la shell) un altro programma. Per +questo si usa la seconda funzione fondamentale per programmazione coi processi +che è la \texttt{exec}. -Esamineremo in questa sezione le varie funzioni per il controllo dei processi: -la loro creazione, la terminazione, l'esecuzione di altri programmi. Prima di -trattare in dettaglio le singole funzioni, faremo un'introduzione generale ai -concetti che stanno alla base della gestione dei processi in unix. +Il programma che un processo sta eseguendo si chiama immagine del processo +(\textit{process image}), le funzioni della famiglia \func{exec} permettono +di caricare un'altro programma da disco sostituendo quest'ultimo alla process +image corrente, questo fa si che la precedente immagine venga completamente +cancellata e quando il nuovo programma esce anche il processo termina, senza +ritornare alla precedente immagine. -\subsection{Una panoramica} -\label{sec:prochand_control_overview} +Per questo motivo la \func{fork} e la \func{exec} sono funzioni molto +particolari con caratteristiche uniche rispetto a tutte le altre, infatti la +prima ritorna due volte (nel processo padre e nel figlio) mentre la seconda +non ritorna mai (in quanto con essa viene eseguito un altro programma). I processi vengono creati dalla funzione \texttt{fork}; in genere questa è una system call, ma Linux però usa un'altra nomenclatura, e la funzione fork è @@ -109,8 +119,45 @@ prima ritorna due volte (nel processo padre e nel figlio) mentre la seconda non ritorna mai (in quanto con essa viene eseguito un altro programma). + +\section{Il controllo dei processi} +\label{sec:proc_control} + +Esamineremo in questa sezione le varie funzioni per il controllo dei processi: +la loro creazione, la terminazione, l'esecuzione di altri programmi. Prima di +trattare in dettaglio le singole funzioni, + +\subsection{Gli identificatori dei processi} +\label{sec:proc_id} + +Ogni processo viene identificato dal sistema da un numero identificativo +unico, il \textit{process id} o \acr{pid}. Questo viene assegnato in forma +progressiva ogni volta che un nuovo processo viene creato, fino ad un limite +massimo (in genere essendo detto numero memorizzato in un intero a 16 bit si +arriva a 32767) oltre il quale si riparte dal numero più basso disponibile +(FIXME: verificare, non sono sicuro). Per questo motivo processo il processo +di avvio (init) ha sempre il pid uguale a uno. + +Ogni processo è identificato univocamente dal sistema per il suo pid; +quest'ultimo è un tipo di dato standard, il \texttt{pid\_t} che in genere è un +intero con segno (nel caso di Linux e delle glibc il tipo usato è +\texttt{int}). + +Tutti i processi inoltre portano traccia del pid del genitore, chiamato in +genere \textit{ppid} (da \textit{Parente Process Id}). Questi identificativi +possono essere ottenuti da un programma usando le funzioni: +\begin{functions} +\headdecl{sys/types.h} +\headdecl{unistd.h} +\funcdecl{pid\_t getpid(void)} restituisce il pid del processo corrente. +\funcdecl{pid\_t getppid(void)} restituisce il pid del padre del processo + corrente. +\end{functions} + + + \subsection{La funzione \func{fork}} -\label{sec:prochand_fork} +\label{sec:proc_fork} La funzione \func{fork} @@ -126,24 +173,24 @@ viene eseguito dal padre o dal figlio. \subsection{Le funzioni \texttt{wait} e \texttt{waitpid}} -\label{sec:prochand_wait} +\label{sec:proc_wait} \subsection{Le funzioni \texttt{exec}} -\label{sec:prochand_exec} +\label{sec:proc_exec} \section{Il controllo di accesso} -\label{sec:prochand_perms} +\label{sec:proc_perms} Va messo qui tutta la storia su effective, real, saved uid, e pure le cose di Linux come il filesystem uid. \subsection{Le funzioni \texttt{setuid} e \texttt{setgid}} -\label{sec:prochand_setuid} +\label{sec:proc_setuid} \subsection{Le funzioni \texttt{seteuid} e \texttt{setegid}} -\label{sec:prochand_seteuid} +\label{sec:proc_seteuid}