X-Git-Url: https://gapil.gnulinux.it/gitweb/?p=gapil.git;a=blobdiff_plain;f=process.tex;h=43dac1d9e82f79237febc7703000a9bf8d51fc18;hp=f2c4f73bde2eb9955619c26c8a402cbd8b1ae26a;hb=9a6d19e384fe9b1afbe4d9124ac34eaf7aa57562;hpb=3b7696e141a7c9c5d9ddec1654aa2a1108350bde diff --git a/process.tex b/process.tex index f2c4f73..43dac1d 100644 --- a/process.tex +++ b/process.tex @@ -54,18 +54,19 @@ dettagli sono riportati nella man page di \cmd{ld.so}. Il sistema fa partire qualunque programma chiamando la funzione \func{main}; sta al programmatore chiamare così la funzione principale del programma da cui si suppone iniziare l'esecuzione; in ogni caso senza questa funzione lo stesso -\textit{linker} darebbe luogo ad errori. - -Lo standard ISO C specifica che la funzione \func{main} può 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: +\textit{linker} (si chiama così il programma che effettua i collegamenti di +cui sopra) darebbe luogo ad errori. Lo standard ISO C specifica che la +funzione \func{main} può 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: \includecodesnip{listati/main_def.c} -In realtà nei sistemi Unix esiste un'altro modo per definire la funzione +In realtà nei sistemi Unix esiste un altro modo per definire la funzione \func{main}, che prevede la presenza di un terzo argomento, \code{char - *envp[]}, che fornisce l'\textsl{ambiente} (vedi sez.~\ref{sec:proc_environ}) -del programma; questa forma però non è prevista dallo standard POSIX.1 per cui -se si vogliono scrivere programmi portabili è meglio evitarla. + *envp[]}, che fornisce (vedi sez.~\ref{sec:proc_environ}) +l'\textsl{ambiente} del programma; questa forma però non è prevista dallo +standard POSIX.1 per cui se si vogliono scrivere programmi portabili è meglio +evitarla. \subsection{Come chiudere un programma} @@ -151,7 +152,7 @@ non vengono salvati e le eventuali funzioni registrate con \func{atexit} e La funzione chiude tutti i file descriptor appartenenti al processo (si tenga presente che questo non comporta il salvataggio dei dati bufferizzati degli -stream), fa sì che ogni figlio del processo sia ereditato da \cmd{init} (vedi +stream), fa sì che ogni figlio del processo sia adottato da \cmd{init} (vedi cap.~\ref{cha:process_handling}), manda un segnale \const{SIGCHLD} al processo padre (vedi sez.~\ref{sec:sig_job_control}) ed infine ritorna lo stato di uscita specificato in \param{status} che può essere raccolto usando la @@ -265,7 +266,7 @@ nell'assegnare ad ogni processo uno spazio virtuale di indirizzamento lineare, in cui gli indirizzi vanno da zero ad un qualche valore massimo.\footnote{nel caso di Linux fino al kernel 2.2 detto massimo era, per macchine a 32bit, di 2Gb. Con il kernel 2.4 ed il supporto per la \textit{high-memory} il limite - è stato esteso.} + è stato esteso anche per macchine a 32 bit.} Come accennato in cap.~\ref{cha:intro_unix} questo spazio di indirizzi è virtuale e non corrisponde all'effettiva posizione dei dati nella RAM del @@ -434,10 +435,10 @@ una funzione e per le sue variabili locali (le cosiddette \textsl{variabili per queste variabili viene allocato nello stack quando viene eseguita la funzione e liberato quando si esce dalla medesima. -Esiste però un terzo tipo di allocazione, l'\textsl{allocazione dinamica della - memoria}, che non è prevista direttamente all'interno del linguaggio C, ma -che è necessaria quando il quantitativo di memoria che serve è determinabile -solo durante il corso dell'esecuzione del programma. +Esiste però un terzo tipo di allocazione, l'\textsl{allocazione dinamica} +della memoria, che non è prevista direttamente all'interno del linguaggio C, +ma che è necessaria quando il quantitativo di memoria che serve è +determinabile solo durante il corso dell'esecuzione del programma. Il C non consente di usare variabili allocate dinamicamente, non è possibile cioè definire in fase di programmazione una variabile le cui dimensioni @@ -544,9 +545,9 @@ uso una versione meno efficiente delle funzioni suddette, che per tollerante nei confronti di piccoli errori come quello di chiamate doppie a \func{free}. In particolare: \begin{itemize} -\item se la variabile è posta a zero gli errori vengono ignorati. +\item se la variabile è posta a zero gli errori vengono ignorati; \item se è posta ad 1 viene stampato un avviso sullo \textit{standard error} - (vedi sez.~\ref{sec:file_std_stream}). + (vedi sez.~\ref{sec:file_std_stream}); \item se è posta a 2 viene chiamata \func{abort}, che in genere causa l'immediata conclusione del programma. \end{itemize} @@ -578,12 +579,13 @@ dell'applicazione in esecuzione. In altri linguaggi come il java e recentemente il C\# il problema non si pone nemmeno perché la gestione della memoria viene fatta totalmente in maniera automatica, ovvero il programmatore non deve minimamente preoccuparsi di -liberare la memoria allocata precedentemente quando non serve più, poiché il -framework gestisce automaticamente la cosiddetta \textit{garbage collection}. -In tal caso, attraverso meccanismi simili a quelli del \textit{reference - counting}, quando una zona di memoria precedentemente allocata non è più -riferita da nessuna parte del codice in esecuzione, può essere deallocata -automaticamente in qualunque momento dall'infrastruttura. +liberare la memoria allocata precedentemente quando non serve più, poiché +l'infrastruttura del linguaggio gestisce automaticamente la cosiddetta +\index{\textit{garbage~collection}}\textit{garbage collection}. In tal caso, +attraverso meccanismi simili a quelli del \textit{reference counting}, quando +una zona di memoria precedentemente allocata non è più riferita da nessuna +parte del codice in esecuzione, può essere deallocata automaticamente in +qualunque momento dall'infrastruttura. Anche questo va a scapito delle prestazioni dell'applicazione in esecuzione (inoltre le applicazioni sviluppate con tali linguaggi di solito non sono @@ -597,7 +599,7 @@ allocata da un oggetto. Per limitare l'impatto di questi problemi, e semplificare la ricerca di eventuali errori, l'implementazione delle routine di allocazione delle \acr{glibc} mette a disposizione una serie di funzionalità che permettono di -tracciare le allocazioni e le disallocazione, e definisce anche una serie di +tracciare le allocazioni e le disallocazioni, e definisce anche una serie di possibili \textit{hook} (\textsl{ganci}) che permettono di sostituire alle funzioni di libreria una propria versione (che può essere più o meno specializzata per il debugging). Esistono varie librerie che forniscono dei @@ -665,11 +667,12 @@ Questo cui torneremo in sez.~\ref{sec:proc_auto_var}. -Queste due funzioni vengono utilizzate soltanto quando è necessario effettuare -direttamente la gestione della memoria associata allo spazio dati di un -processo, ad esempio qualora si debba implementare la propria versione delle -routine di allocazione della memoria viste in sez.~\ref{sec:proc_mem_malloc}. -La prima funzione è \funcd{brk}, ed il suo prototipo è: +Le due funzioni seguenti vengono utilizzate soltanto quando è necessario +effettuare direttamente la gestione della memoria associata allo spazio dati +di un processo, ad esempio qualora si debba implementare la propria versione +delle routine di allocazione della memoria viste in +sez.~\ref{sec:proc_mem_malloc}. La prima funzione è \funcd{brk}, ed il suo +prototipo è: \begin{prototype}{unistd.h}{int brk(void *end\_data\_segment)} Sposta la fine del segmento dei dati. @@ -764,7 +767,7 @@ bloccata oppure no. Il \textit{memory lock} persiste fintanto che il processo che detiene la memoria bloccata non la sblocca. Chiaramente la terminazione del processo comporta anche la fine dell'uso della sua memoria virtuale, e quindi anche di -tutti i suoi \textit{memory lock}. Infine \textit{memory lock} non sono +tutti i suoi \textit{memory lock}. Infine i \textit{memory lock} non sono ereditati dai processi figli.\footnote{ma siccome Linux usa il \textit{copy on write} (vedi sez.~\ref{sec:proc_fork}) gli indirizzi virtuali del figlio sono mantenuti sullo stesso segmento di RAM del padre, quindi fintanto che @@ -888,13 +891,13 @@ manipolare ed utilizzare le variabili di ambiente. \subsection{Il formato degli argomenti} \label{sec:proc_par_format} -In genere passaggio degli argomenti al programma viene effettuato dalla shell, -che si incarica di leggere la linea di comando e di effettuarne la scansione -(il cosiddetto \textit{parsing}) per individuare le parole che la compongono, -ciascuna delle quali viene considerata un argomento. Di norma per individuare -le parole viene usato come carattere di separazione lo spazio o il tabulatore, -ma il comportamento è modificabile attraverso l'impostazione della variabile -di ambiente \cmd{IFS}. +In genere il passaggio degli argomenti al programma viene effettuato dalla +shell, che si incarica di leggere la linea di comando e di effettuarne la +scansione (il cosiddetto \textit{parsing}) per individuare le parole che la +compongono, ciascuna delle quali viene considerata un argomento. Di norma per +individuare le parole viene usato come carattere di separazione lo spazio o il +tabulatore, ma il comportamento è modificabile attraverso l'impostazione della +variabile di ambiente \cmd{IFS}. \begin{figure}[htb] \centering @@ -954,7 +957,7 @@ La modalit funzione all'interno di un ciclo, fintanto che essa non ritorna il valore -1 che indica che non ci sono più opzioni. Nel caso si incontri un'opzione non dichiarata in \param{optstring} viene ritornato il carattere \texttt{'?'} -mentre se un opzione che lo richiede non è seguita da un parametro viene +mentre se un'opzione che lo richiede non è seguita da un parametro viene ritornato il carattere \texttt{':'}, infine se viene incontrato il valore \texttt{'-{}-'} la scansione viene considerata conclusa, anche se vi sono altri elementi di \param{argv} che cominciano con il carattere \texttt{'-'}. @@ -1015,7 +1018,7 @@ effettua il riordinamento del vettore \param{argv}. \subsection{Opzioni in formato esteso} \label{sec:proc_opt_extended} -Un'estensione di questo schema è costituito dalle cosiddette +Un'estensione di questo schema è costituita dalle cosiddette \textit{long-options} espresse nella forma \cmd{-{}-option=parameter}, anche la gestione di queste ultime è stata standardizzata attraverso l'uso di una versione estesa di \func{getopt}. @@ -1070,7 +1073,7 @@ delle relative chiamate (si veda sez.~\ref{sec:proc_exec}). La shell ad esempio ne usa molte per il suo funzionamento (come \texttt{PATH} per la ricerca dei comandi, o \texttt{IFS} per la scansione degli argomenti), -e alcune di esse (come \texttt{HOME}, \texttt{USER}, etc.) sono definite al +e alcune di esse (come \texttt{HOME}, \texttt{USER}, ecc.) sono definite al login (per i dettagli si veda sez.~\ref{sec:sess_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 @@ -1080,7 +1083,7 @@ necessit Gli standard POSIX e XPG3 definiscono alcune di queste variabili (le più comuni), come riportato in tab.~\ref{tab:proc_env_var}. GNU/Linux le supporta tutte e ne definisce anche altre: per una lista più completa si può -controllare \cmd{man environ}. +controllare \cmd{man 5 environ}. \begin{table}[htb] \centering @@ -1195,7 +1198,7 @@ separatamente nome e valore della variabile di ambiente, inoltre il valore di variabile esista già, sovrascrivendola se diverso da zero, lasciandola immutata se uguale a zero. -La seconda funzione prende come argomento una stringa analoga quella +La seconda funzione prende come argomento una stringa analoga a quella restituita da \func{getenv}, e sempre nella forma \code{NOME=valore}. Se la variabile specificata non esiste la stringa sarà aggiunta all'ambiente, se invece esiste il suo valore sarà impostato a quello specificato da @@ -1305,7 +1308,7 @@ numero fisso di argomenti per una funzione. Lo standard ISO C prevede nella sua sintassi la possibilità di definire delle \textit{variadic function}\index{variadic} che abbiano un numero variabile di argomenti, attraverso l'uso nella dichiarazione della funzione dello speciale costrutto -``\texttt{...}'', che viene chiamato \textit{ellipsis}. +``\texttt{\textellipsis}'', che viene chiamato \textit{ellipsis}. Lo standard però non provvede a livello di linguaggio alcun meccanismo con cui dette funzioni possono accedere ai loro argomenti. L'accesso viene pertanto @@ -1359,7 +1362,7 @@ macro; la procedura da seguire \item Dichiarare la conclusione dell'estrazione degli argomenti invocando la macro \macro{va\_end}. \end{enumerate} -in generale è perfettamente legittimo richiedere meno argomenti di quelli che +In generale è perfettamente legittimo richiedere meno argomenti di quelli che potrebbero essere stati effettivamente forniti, e nella esecuzione delle \macro{va\_arg} ci si può fermare in qualunque momento ed i restanti argomenti saranno ignorati; se invece si richiedono più argomenti di quelli forniti si @@ -1578,13 +1581,13 @@ chiamate a questa funzione sono sicure solo in uno dei seguenti casi: espressione di controllo di un comando condizionale, di selezione o di iterazione; \item come operando per l'operatore di negazione (\code{!}) in una espressione - di controllo di un comando condizionale, di selezione o di iterazione. + di controllo di un comando condizionale, di selezione o di iterazione; \item come espressione a sé stante. \end{itemize} In generale, dato che l'unica differenza fra la chiamata diretta e quella -ottenuta da un \func{longjmp}, è il valore di ritorno di \func{setjmp}, essa è -usualmente chiamata all'interno di un comando \code{if}. +ottenuta da un \func{longjmp} è costituita dal valore di ritorno di +\func{setjmp}, essa è usualmente chiamata all'interno di un comando \code{if}. Uno dei punti critici dei salti non-locali è quello del valore delle variabili, ed in particolare quello delle variabili automatiche della funzione