X-Git-Url: https://gapil.gnulinux.it/gitweb/?p=gapil.git;a=blobdiff_plain;f=process.tex;h=e663713f93584f9029a0cc657cbee66cd7bed344;hp=c19ebe615c73a90b628571ae55c79f4fe18161ba;hb=d99b4995b23505a9afde30adf3a716aa7a55f0e9;hpb=056bbc90c8a0710b57fa7b13f5f0dfdad1b3ff3f diff --git a/process.tex b/process.tex index c19ebe6..e663713 100644 --- a/process.tex +++ b/process.tex @@ -53,9 +53,9 @@ linker darebbe luogo ad errori. Lo standard ISO C specifica che la funzione \texttt{main} può o non avere argomenti o prendere due argomenti che rappresentano gli argomenti passati da linea di comando, in sostanza un prototipo che va sempre bene è il seguente: -\begin{verbatim} +\begin{lstlisting}[labelstep=0,frame=,indent=1cm]{} int main (int argc, char *argv[]) -\end{verbatim} +\end{lstlisting} In realtà nei sistemi unix esiste un'altro modo per definire la funzione \texttt{main}, che prevede la presenza di un terzo parametro, \texttt{char @@ -347,9 +347,9 @@ programma C viene suddiviso nei seguenti segmenti: La prima parte è il segmento dei dati inizializzati, che contiene le variabili globali il cui valore è stato assegnato esplicitamente. Ad esempio se si definisce: -\begin{verbatim} +\begin{lstlisting}[labelstep=0,frame=,indent=1cm]{} double pi = 3.14; -\end{verbatim} +\end{lstlisting} questo valore sarà immagazzinato in questo segmento. La memoria di questo segmento viene preallocato dalla \texttt{exec} e inizializzata ai valori specificati. @@ -357,9 +357,9 @@ programma C viene suddiviso nei seguenti segmenti: La seconda parte è il segmento dei dati non inizializzati, che contiene le variabili globali il cui valore è stato non è assegnato esplicitamente. Ad esempio se si definisce: -\begin{verbatim} +\begin{lstlisting}[labelstep=0,frame=,indent=1cm]{} int vect[100]; -\end{verbatim} +\end{lstlisting} questo valore sarà immagazzinato in questo segmento. Anch'esso viene allocato all'avvio, e tutte le variabili vengono inizializzate a zero (ed i puntatori a \texttt{NULL}). @@ -388,7 +388,7 @@ programma C viene suddiviso nei seguenti segmenti: \begin{figure}[htb] \centering - + \includegraphics[width=5cm]{img/memory_layout.eps} \caption{Disposizione tipica dei segmenti di memoria di un processo} \label{fig:proc_mem_layout} \end{figure} @@ -496,13 +496,12 @@ la funzione lo utilzza, altrimenti rialloca altrove un blocco della dimensione voluta copiandoci automaticamente il contenuto, lo spazio in più non viene inizializzato. -Il fatto che il blocco di memoria restituito da \texttt{realloc} possa -camabiare comporta che si deve sempre riassegnare al puntatore passato per il +Il fatto che il blocco di memoria restituito da \func{realloc} possa +cambiare comporta che si deve sempre riassegnare al puntatore passato per il ridimensionamento il valore di ritorno della funzione, e che non ci devono essere altri puntatori che puntino all'interno di un'area che si vuole ridimensionare. - Uno degli errori più comuni (specie se si ha a che fare con array di puntatori) è infatti quello di chiamare \texttt{free} più di una volta sullo stesso puntatore; per evitare questo problema una soluzione di ripiego è @@ -538,6 +537,7 @@ le disallocazione, e definisce anche una serie di possibili agganci che permettono di sostituire alle funzioni di libreria una propria versione (che può essere più o meno specializzata per il debugging). + \subsection{La funzione \texttt{alloca}} \label{sec:proc_mem_alloca} @@ -559,8 +559,8 @@ viene rilasciata automaticamente al ritorno della funzione. Come è evidente questa funzione ha molti vantaggi, e permette di evitare i problemi di memory leak non essendo più necessaria la deallocazione esplicita; una delle ragioni principali per usarla è però che funziona anche quando si -usa \texttt{longjump} per uscire con un salto non locale da una funzione (vedi -\secref{sec:proc_longjmp}), +usa \func{longjump} per uscire con un salto non locale da una funzione (vedi +\secref{sec:proc_longjmp}), Un altro vantaggio e che in Linux la funzione è molto veloce e non viene sprecato spazio, infatti non è necessario gestire un pool di memoria da @@ -573,6 +573,17 @@ cerca di allocare troppa memoria non si ottiene un messaggio di errore, ma un segnale di \textit{segmentation violation} analogo a quello che si avrebbe da una ricorsione infinita. +Inoltre non è chiaramente possibile usare questa funzione per allocare memoria +che deve poi essere usata anche al di fuori della funzione in cui questa viene +chiamata, in quanto all'uscita dalla funzione lo spazio allocato diventerebbe +libero, e potrebbe essere sovrascritto all'invocazione di nuove funzioni con +conseguenze imprevedibili. + +Questo è lo stesso problema potenziale che si può avere con le variabili +automatiche; un errore comune infatti è quello di restituire al chiamante un +puntatore ad una di queste variabili, che sarà automaticamente distrutta +all'uscita della funzione, con gli stessi problemi appena citati per +\func{alloca}. \subsection{Le funzioni \texttt{brk} e \texttt{sbrk}} \label{sec:proc_mem_sbrk} @@ -668,14 +679,12 @@ memoria di un processo che pu che può dedicare a questo. - - \section{Il controllo di flusso non locale} \label{sec:proc_longjmp} Il controllo del flusso di un programma in genere viene effettuato con le varie istruzioni del linguaggio C, la più bistrattata delle quali è il -\texttt{goto} ampiamente deprecato in favore di costrutti più puliti; esiste +\texttt{goto}, ampiamente deprecato in favore di costrutti più puliti; esiste però un caso in l'uso di questa istruzione porta all'implementazione più efficiente, quello dell'uscita in caso di errore. @@ -820,3 +829,53 @@ versione estesa di \texttt{getopt}. \subsection{Le variabili di ambiente} \label{sec:proc_environ} +Oltre ai parametri passati da linea di comando ogni processo riceve dal +sistema un \textsl{ambiente}, nella forma di una lista di variabili +(\textit{environment list}) messa a disposizione dal processo costruita nella +chiamata ad \func{exec} che lo ha lanciato. + +Come per la lista dei parametri anche questa lista è un array di puntatori a +caratteri, ciascuno dei quali punta ad una stringa (terminata da un null). A +differenza di \var{argv[]} però in questo caso non si ha la lunghezza +dell'array dato da un equivalente di \var{argc}, ma la lista è terminata da un +puntatore nullo. + +L'indirizzo della lista delle variabili di ambiente è passato attraverso la +variabile globale \var{environ}, a cui si può accedere attraverso una semplice +dichiarazione del tipo: +\begin{lstlisting}[labelstep=0,frame=,indent=1cm]{} +extern char ** environ; +\end{lstlisting} +un esempio del contenuto dell'ambiente, in si è riportato un estratto delle +variabili che normalmente sono definite dal sistema, è riportato in \nfig. +\begin{figure}[htb] + \centering + \includegraphics[width=11cm]{img/environ_var.eps} + \caption{Esempio di lista delle variabili di ambiente.} + \label{fig:proc_envirno_list} +\end{figure} + +Per convenzione le stringhe che definiscono l'ambiente sono tutte del tipo +\textsl{\texttt{nome=valore}}. Inoltre alcune variabili, come quelle elencate +in \curfig, sono definite dal sistema per queste c'è la convezione di usare +nomi espressi in caratteri maiuscoli. + +Il kernel non usa mai queste variabili, il loro uso e la loro intepretazione è +riservata alle applicazioni e ad alcune funzioni di libreria; in genere esse +costituiscono un modo comodo per definire un comportamento specifico senza +dover ricorrere all'uso di opzioni a linea di comando o di file di +configurazione. + +La shell ad esempio ne usa molte per il suo funzionamento (come \var{PATH} per +la ricerca dei comadi), e alcune di esse (come \var{HOME}, \var{USER}, etc.) +sono definite al login. In genere è cura dell'amministratore definire le +opportune variabili di ambiente in uno script di avvio. Alcune servono poi +come riferimento generico per molti programmi (come \var{EDITOR} che indica +l'editor preferito da invocare in caso di ncessità). + +Gli standard POSIX e XPG3 definiscono alcune di queste variabili (le più +comuni), come riportato in \ntab. GNU/Linux le supporta tutte e ne definisce +anche altre per una lista parziale si può controllare \cmd{man environ} + + +