From 47a00595786c34a03266f19dd5163a45da63e29f Mon Sep 17 00:00:00 2001 From: Simone Piccardi Date: Mon, 10 Dec 2007 14:26:00 +0000 Subject: [PATCH] Alcune correzioni ai font dei link, e una trattazione esplicita dell'ordine di esecuzione dei processi dopo una {{{fork}} cambiato con il 2.6... --- fileadv.tex | 6 ++--- ipc.tex | 2 +- prochand.tex | 63 ++++++++++++++++++++++++++++------------------ ringraziamenti.tex | 2 +- sockctrl.tex | 18 ++++++------- socket.tex | 2 +- tcpsock.tex | 2 +- 7 files changed, 55 insertions(+), 40 deletions(-) diff --git a/fileadv.tex b/fileadv.tex index ee802fb..1ba5b99 100644 --- a/fileadv.tex +++ b/fileadv.tex @@ -2910,7 +2910,7 @@ che anzi in certi casi si potevano avere anche dei peggioramenti. Questo ha portato, per i kernel della serie 2.6,\footnote{per alcune motivazioni di questa scelta si può fare riferimento a quanto illustrato da Linus Torvalds in \href{http://www.cs.helsinki.fi/linux/linux-kernel/2001-03/0200.html} - {\texttt{http://www.cs.helsinki.fi/linux/linux-kernel/2001-03/0200.html}}.} + {\textsf{http://www.cs.helsinki.fi/linux/linux-kernel/2001-03/0200.html}}.} alla decisione di consentire l'uso della funzione soltanto quando il file da cui si legge supporta le operazioni di \textit{memory mapping} (vale a dire non è un socket) e quello su cui si scrive è un socket; in tutti gli altri @@ -2953,7 +2953,7 @@ Il concetto che sta dietro a \func{splice} invece stata la reinterpretazione che ne è stata fatta nell'implementazione su Linux realizzata da Jens Anxboe, concetti che sono esposti sinteticamente dallo stesso Linus Torvalds in \href{http://kerneltrap.org/node/6505} - {\texttt{http://kerneltrap.org/node/6505}}.} si tratta semplicemente di una + {\textsf{http://kerneltrap.org/node/6505}}.} si tratta semplicemente di una funzione che consente di fare in maniera del tutto generica delle operazioni di trasferimento di dati fra un file e un buffer gestito interamente in kernel space. In questo caso il cuore della funzione (e delle affini \func{vmsplice} @@ -3337,7 +3337,7 @@ detto che i dati vengono effettivamente spostati o copiati, il kernel infatti realizza le \textit{pipe} come un insieme di puntatori\footnote{per essere precisi si tratta di un semplice buffer circolare, un buon articolo sul tema si trova su \href{http://lwn.net/Articles/118750/} - {\texttt{http://lwn.net/Articles/118750/}}.} alle pagine di memoria interna + {\textsf{http://lwn.net/Articles/118750/}}.} alle pagine di memoria interna che contengono i dati, per questo una volta che i dati sono presenti nella memoria del kernel tutto quello che viene fatto è creare i suddetti puntatori ed aumentare il numero di referenze; questo significa che anche con \func{tee} diff --git a/ipc.tex b/ipc.tex index 384a2d3..e17fe6d 100644 --- a/ipc.tex +++ b/ipc.tex @@ -3322,7 +3322,7 @@ Le code di messaggi POSIX sono supportate da Linux a partire dalla versione 2.6.6-rc1 del kernel,\footnote{l'implementazione è dovuta a Michal Wronski e Krzysztof Benedyczak, e le relative informazioni si possono trovare su \href{http://www.geocities.com/wronski12/posix_ipc/index.html} - {\texttt{http://www.geocities.com/wronski12/posix\_ipc/index.html}}.} In + {\textsf{http://www.geocities.com/wronski12/posix\_ipc/index.html}}.} In generale, come le corrispettive del SysV IPC, le code di messaggi sono poco usate, dato che i socket, nei casi in cui sono sufficienti, sono più comodi, e che in casi più complessi la comunicazione può essere gestita direttamente con diff --git a/prochand.tex b/prochand.tex index 94d316e..3522bbb 100644 --- a/prochand.tex +++ b/prochand.tex @@ -194,9 +194,9 @@ abbastanza limitata sulle cause della terminazione del processo figlio. Quando un processo ha concluso il suo compito o ha incontrato un errore non risolvibile esso può essere terminato con la funzione \func{exit} (si veda quanto discusso in sez.~\ref{sec:proc_conclusion}). La vita del processo però -termina solo quando la notifica della sua conclusione viene ricevuta dal -processo padre, a quel punto tutte le risorse allocate nel sistema ad esso -associate vengono rilasciate. +termina completamente solo quando la notifica della sua conclusione viene +ricevuta dal processo padre, a quel punto tutte le risorse allocate nel +sistema ad esso associate vengono rilasciate. Avere due processi che eseguono esattamente lo stesso codice non è molto utile, normalmente si genera un secondo processo per affidargli l'esecuzione @@ -431,7 +431,6 @@ Se eseguiamo il comando\footnote{che senza specificare attese (come si può notare in (\texttt{\small 17--19}) i valori predefiniti specificano di non attendere), otterremo come output sul terminale: - \footnotesize \begin{verbatim} [piccardi@selidor sources]$ export LD_LIBRARY_PATH=./; ./forktest 3 @@ -452,17 +451,14 @@ Go to next child \normalsize Esaminiamo questo risultato: una prima conclusione che si può trarre è che non -si può dire quale processo fra il padre ed il figlio venga eseguito per -primo\footnote{a partire dal kernel 2.5.2-pre10 è stato introdotto il nuovo - \itindex{scheduler} \textit{scheduler} di Ingo Molnar che esegue sempre per - primo il figlio; per mantenere la portabilità è opportuno non fare comunque - affidamento su questo comportamento.} dopo la chiamata a \func{fork}; -dall'esempio si può notare infatti come nei primi due cicli sia stato eseguito -per primo il padre (con la stampa del \acr{pid} del nuovo processo) per poi -passare all'esecuzione del figlio (completata con i due avvisi di esecuzione -ed uscita), e tornare all'esecuzione del padre (con la stampa del passaggio al -ciclo successivo), mentre la terza volta è stato prima eseguito il figlio -(fino alla conclusione) e poi il padre. +si può dire quale processo fra il padre ed il figlio venga eseguito per primo +dopo la chiamata a \func{fork}; dall'esempio si può notare infatti come nei +primi due cicli sia stato eseguito per primo il padre (con la stampa del +\acr{pid} del nuovo processo) per poi passare all'esecuzione del figlio +(completata con i due avvisi di esecuzione ed uscita), e tornare +all'esecuzione del padre (con la stampa del passaggio al ciclo successivo), +mentre la terza volta è stato prima eseguito il figlio (fino alla conclusione) +e poi il padre. In generale l'ordine di esecuzione dipenderà, oltre che dall'algoritmo di \itindex{scheduler} scheduling usato dal kernel, dalla particolare situazione @@ -479,6 +475,24 @@ occorrer rischio di incorrere nelle cosiddette \itindex{race~condition} \textit{race condition} (vedi sez.~\ref{sec:proc_race_cond}). +In realtà a partire dal kernel 2.5.2-pre10 il nuovo \itindex{scheduler} +\textit{scheduler} di Ingo Molnar esegue sempre per primo il +figlio;\footnote{i risultati precedenti sono stati ottenuti su un kernel della + serie 2.4.} questa è una ottimizzazione che serve a evitare che il padre, +effettuando per primo una operazione di scrittura in memoria, attivi il +meccanismo del \itindex{copy~on~write} \textit{copy on write}. Questa +operazione infatti potrebbe risultare del tutto inutile qualora il figlio +fosse stato creato solo per eseguire una \func{exec}, in tal caso infatti si +invocherebbe un'altro proramma scartando completamente lo spazio degli +indirizzi, rendendo superflua la copia della memoria modificata dal padre. + +Eseguendo sempre per primo il figlio la \func{exec} verrebbe effettuata subito +avendo così la certezza che il \itindex{copy~on~write} \textit{copy on write} +viene utilizzato solo quando necessario. Quanto detto in precedenza vale +allora soltanto per i kernel fino al 2.4, per mantenere la portabilità è però +opportuno non fare affidamento su questo comportamento, che non si riscontra +in altri Unix e nelle versioni del kernel precendenti a quella indicata. + Si noti inoltre che essendo i segmenti di memoria utilizzati dai singoli processi completamente separati, le modifiche delle variabili nei processi figli (come l'incremento di \var{i} in \texttt{\small 31}) sono visibili solo @@ -490,7 +504,6 @@ Un secondo aspetto molto importante nella creazione dei processi figli quello dell'interazione dei vari processi con i file; per illustrarlo meglio proviamo a redirigere su un file l'output del nostro programma di test, quello che otterremo è: - \footnotesize \begin{verbatim} [piccardi@selidor sources]$ ./forktest 3 > output @@ -538,7 +551,7 @@ ogni figlio riceve una copia della memoria del padre, esso ricever quanto c'è nel buffer delle funzioni di I/O, comprese le linee scritte dal padre fino allora. Così quando il buffer viene scritto su disco all'uscita del figlio, troveremo nel file anche tutto quello che il processo padre aveva -scritto prima della sua creazione. E alla fine del file (dato che in questo +scritto prima della sua creazione. E alla fine del file (dato che in questo caso il padre esce per ultimo) troveremo anche l'output completo del padre. L'esempio ci mostra un altro aspetto fondamentale dell'interazione con i file, @@ -727,6 +740,8 @@ che sia cos terminato (si potrebbe avere cioè quello che si chiama un processo \textsl{orfano}). +% TODO verificare il reparenting + Questa complicazione viene superata facendo in modo che il processo orfano venga \textsl{adottato} da \cmd{init}. Come già accennato quando un processo termina, il kernel controlla se è il padre di altri processi in esecuzione: in @@ -736,7 +751,6 @@ avr cui riportare il suo stato di terminazione. Come verifica di questo comportamento possiamo eseguire il nostro programma \cmd{forktest} imponendo a ciascun processo figlio due secondi di attesa prima di uscire, il risultato è: - \footnotesize \begin{verbatim} [piccardi@selidor sources]$ ./forktest -c2 3 @@ -1227,7 +1241,8 @@ ritorno di \func{waitid} verranno avvalorati i seguenti campi: \const{CLD\_STOPPED}, \const{CLD\_CONTINUED} (vedi tab.~\ref{xxx_si_code}). \end{basedescript} -%TODO mettere riferimento alla tabella giusta +%TODO mettere riferimento alla tabella giusta (vedere man credentials e man +% waitid) Infine Linux, seguendo un'estensione di BSD, supporta altre due funzioni per la lettura dello stato di terminazione di un processo, analoghe alle @@ -1256,7 +1271,7 @@ utilizzata anche dalla funzione \func{getrusage} (vedi sez.~\ref{sec:sys_resource_use}) per ottenere le risorse di sistema usate da un processo; la sua definizione è riportata in fig.~\ref{fig:sys_rusage_struct}. -\subsection{Le funzioni \func{exec}} +\subsection{La funzione \func{exec} e le funzioni di esecuzione dei programmi} \label{sec:proc_exec} Abbiamo già detto che una delle modalità principali con cui si utilizzano i @@ -1489,7 +1504,7 @@ chiamato come se si fosse eseguito il comando \cmd{interpreter [argomenti] lunga restituisce un errore di \const{ENAMETOOLONG}, una comparazione dei vari comportamenti si trova su \href{http://www.in-ulm.de/~mascheck/various/shebang/} - {\texttt{http://www.in-ulm.de/\tild mascheck/various/shebang/}}.} + {\textsf{http://www.in-ulm.de/\tild mascheck/various/shebang/}}.} Con la famiglia delle \func{exec} si chiude il novero delle funzioni su cui è basata la gestione dei processi in Unix: con \func{fork} si crea un nuovo @@ -2116,7 +2131,7 @@ implementata.\footnote{per attualmente si intende fino al kernel 2.6.23; benché l'infrastruttura per crearla sia presente (vedi anche sez.~\ref{sec:file_xattr}) finora non è disponibile nessuna realizzazione delle specifiche POSIX.1e, esistono però dei patch di sicurezza del kernel, - come LIDS (vedi \href{http://www.lids.org}{\texttt{http://www.lids.org/})} + come LIDS (vedi \href{http://www.lids.org}{\textsf{http://www.lids.org/})} che realizzano qualcosa di simile.} @@ -3097,7 +3112,7 @@ tocca al kernel decidere quale deve essere eseguito. Il meccanismo con cui vengono gestiti questi processi dipende dalla politica di scheduling che si è scelta; lo standard ne prevede due: \begin{basedescript}{\desclabelwidth{1.2cm}\desclabelstyle{\nextlinelabel}} -\item[\textit{FIFO}] \textit{First In First Out}. Il processo viene eseguito +\item[\textsf{FIFO}] \textit{First In First Out}. Il processo viene eseguito fintanto che non cede volontariamente la CPU (con \func{sched\_yield}), si blocca, finisce o viene interrotto da un processo a priorità più alta. Se il processo viene interrotto da uno a priorità più alta esso resterà in cima @@ -3105,7 +3120,7 @@ scelta; lo standard ne prevede due: più alta diverranno inattivi. Se invece lo si blocca volontariamente sarà posto in coda alla lista (ed altri processi con la stessa priorità potranno essere eseguiti). -\item[\textit{RR}] \textit{Round Robin}. Il comportamento è del tutto analogo +\item[\textsf{RR}] \textit{Round Robin}. Il comportamento è del tutto analogo a quello precedente, con la sola differenza che ciascun processo viene eseguito al massimo per un certo periodo di tempo (la cosiddetta \textit{time slice}) dopo di che viene automaticamente posto in fondo alla diff --git a/ringraziamenti.tex b/ringraziamenti.tex index d852d17..13f40a9 100644 --- a/ringraziamenti.tex +++ b/ringraziamenti.tex @@ -36,7 +36,7 @@ presente la prima versione della Guida, lo spazio web, e Truelite Srl, che fornisce il nuovo repository SVN, tutto quanto è necessario alla pubblicazione della guida ed il sistema di tracciamento dei sorgenti su \href{http://gapil.truelite.it/sources} -{\texttt{http://gapil.truelite.it/sources}}. +{\textsf{http://gapil.truelite.it/sources}}. % LocalWords: GaPiL Masini calling convention Maischberger HTML Group FLUG CVS diff --git a/sockctrl.tex b/sockctrl.tex index dc300a8..ed3ca3a 100644 --- a/sockctrl.tex +++ b/sockctrl.tex @@ -1224,7 +1224,7 @@ nuova. La prima funzione di questa interfaccia è \funcd{getaddrinfo},\footnote{la funzione è definita, insieme a \func{getnameinfo} che vedremo più avanti, - nell'\href{http://www.ietf.org/rfc/rfc2553.txt} {RFC~2553}.} che combina le + nell'\href{http://www.ietf.org/rfc/rfc2553.txt}{RFC~2553}.} che combina le funzionalità delle precedenti \func{getipnodebyname}, \func{getipnodebyaddr}, \func{getservbyname} e \func{getservbyport}, consentendo di ottenere contemporaneamente sia la risoluzione di un indirizzo simbolico che del nome @@ -3420,28 +3420,28 @@ quantit reno& -- &Algoritmo tradizionale, usato in caso di assenza degli altri.\\ \texttt{bic} &\texttt{TCP\_CONG\_BIC} & \href{http://www.csc.ncsu.edu/faculty/rhee/export/bitcp/index.htm} - {\texttt{http://www.csc.ncsu.edu/faculty/rhee/export/bitcp/index.htm}}.\\ + {\textsf{http://www.csc.ncsu.edu/faculty/rhee/export/bitcp/index.htm}}.\\ \texttt{cubic} &\texttt{TCP\_CONG\_CUBIC} & \href{http://www.csc.ncsu.edu/faculty/rhee/export/bitcp/index.htm} - {\texttt{http://www.csc.ncsu.edu/faculty/rhee/export/bitcp/index.htm}}.\\ + {\textsf{http://www.csc.ncsu.edu/faculty/rhee/export/bitcp/index.htm}}.\\ \texttt{highspeed}&\texttt{TCP\_CONG\_HSTCP} & \href{http://www.icir.org/floyd/hstcp.html} - {\texttt{http://www.icir.org/floyd/hstcp.html}}.\\ + {\textsf{http://www.icir.org/floyd/hstcp.html}}.\\ \texttt{htcp} &\texttt{TCP\_CONG\_HTCP} & \href{http://www.hamilton.ie/net/htcp/} - {\texttt{http://www.hamilton.ie/net/htcp/}}.\\ + {\textsf{http://www.hamilton.ie/net/htcp/}}.\\ \texttt{hybla} &\texttt{TCP\_CONG\_HYBLA} & \href{http://www.danielinux.net/projects.html} - {\texttt{http://www.danielinux.net/projects.html}}.\\ + {\textsf{http://www.danielinux.net/projects.html}}.\\ \texttt{scalable}&\texttt{TCP\_CONG\_SCALABLE}& \href{http://www.deneholme.net/tom/scalable/} - {\texttt{http://www.deneholme.net/tom/scalable/}}.\\ + {\textsf{http://www.deneholme.net/tom/scalable/}}.\\ \texttt{vegas} &\texttt{TCP\_CONG\_VEGAS} & \href{http://www.cs.arizona.edu/protocols/} - {\texttt{http://www.cs.arizona.edu/protocols/}}.\\ + {\textsf{http://www.cs.arizona.edu/protocols/}}.\\ \texttt{westwood}&\texttt{TCP\_CONG\_WESTWOOD}& \href{http://www.cs.ucla.edu/NRL/hpi/tcpw/} - {\texttt{http://www.cs.ucla.edu/NRL/hpi/tcpw/}}.\\ + {\textsf{http://www.cs.ucla.edu/NRL/hpi/tcpw/}}.\\ % \texttt{}&\texttt{}& .\\ \hline \end{tabular} diff --git a/socket.tex b/socket.tex index 8195f9d..521c241 100644 --- a/socket.tex +++ b/socket.tex @@ -619,7 +619,7 @@ implementare dei protocolli in user space, agendo direttamente sul livello fisico. In genere comunque si preferisce usare la libreria \file{pcap},\footnote{la libreria è mantenuta insieme al comando \cmd{tcpdump}, informazioni e documentazione si possono trovare sul sito del - progetto \href{http://www.tcpdump.org/}{\texttt{http://www.tcpdump.org/}}.} + progetto \href{http://www.tcpdump.org/}{\textsf{http://www.tcpdump.org/}}.} che assicura la portabilità su altre piattaforme, anche se con funzionalità ridotte. diff --git a/tcpsock.tex b/tcpsock.tex index 5378a2d..e4d45be 100644 --- a/tcpsock.tex +++ b/tcpsock.tex @@ -481,7 +481,7 @@ l'elenco delle porte assegnate dalla IANA (la \textit{Internet Assigned Number Authority}) ma l'elenco viene costantemente aggiornato e pubblicato su internet (una versione aggiornata si può trovare all'indirizzo \href{http://www.iana.org/assignments/port-numbers} -{\texttt{http://www.iana.org/assignments/port-numbers}}); inoltre in un +{\textsf{http://www.iana.org/assignments/port-numbers}}); inoltre in un sistema unix-like un analogo elenco viene mantenuto nel file \conffile{/etc/services}, con la corrispondenza fra i vari numeri di porta ed il nome simbolico del servizio. I numeri sono divisi in tre intervalli: -- 2.30.2