From: Simone Piccardi Date: Sun, 11 Aug 2002 11:02:21 +0000 (+0000) Subject: revisioni varie X-Git-Url: https://gapil.gnulinux.it/gitweb/?p=gapil.git;a=commitdiff_plain;h=6a27b6ddf1f27d332f1de65b7c4ac0e1293c2174;hp=c00fca809a709ea67ab3dfdede3a83ead0a9fcaf revisioni varie --- diff --git a/fileadv.tex b/fileadv.tex index 687d7cd..0e0c2b3 100644 --- a/fileadv.tex +++ b/fileadv.tex @@ -546,17 +546,8 @@ errore; il suo prototipo \param{aiocbp}. \bodydesc{La funzione restituisce 0 se le operazioni si sono concluse con - successo, altrimenti restituisce il codice di errore.} -% }, che viene salvato -% anche in \var{errno}, i valori possibili sono: -% \begin{errlist} -% \item[\macro{ENOSYS}] La funzione non è implementata. -% \item[\macro{EINPROGRESS}] L'operazione è ancora in corso. -% \item[\macro{EINVAL}] Si è specificato un valore non valido per i campi -% \var{aio\_offset} o \var{aio\_reqprio} di \param{aiocbp}. -% \item[\macro{EBADF}] Si è specificato un file descriptor sbagliato. -% \end{errlist} -% più tutti quelli possibili per le sottostanti operazioni, .} + successo, altrimenti restituisce il codice di errore relativo al loro + fallimento.} \end{prototype} Se l'operazione non si è ancora completata viene restituito l'errore di @@ -765,11 +756,11 @@ operazioni. Per questo motivo BSD 4.2\footnote{Le due funzioni sono riprese da BSD4.4 ed integrate anche dallo standard Unix 98; fino alle libc5 Linux usava \type{size\_t} come tipo dell'argomento \param{count}, una scelta logica, - che è stata dismessa per restare aderenti allo standard.} ha introdotto due -nuove system call, \func{readv} e \func{writev}, che permettono di effettuare -con una sola chiamata una lettura o una scrittura su una serie di buffer -(quello che viene chiamato \textsl{I/O vettorizzato}. I relativi prototipi -sono: + che però è stata dismessa per restare aderenti allo standard.} ha introdotto +due nuove system call, \func{readv} e \func{writev}, che permettono di +effettuare con una sola chiamata una lettura o una scrittura su una serie di +buffer (quello che viene chiamato \textsl{I/O vettorizzato}. I relativi +prototipi sono: \begin{functions} \headdecl{sys/uio.h} @@ -821,10 +812,12 @@ struct iovec { \label{fig:file_iovec} \end{figure} -I buffer da utilizzare sono specificati attraverso l'argomento \var{vector} che -è un vettore di tale strutture, la cui lunghezza è specificata da \param{count}. -Essi verranno letti (o scritti) nell'ordine in cui li si sono specificati. - +I buffer da utilizzare sono indicati attraverso l'argomento \param{vector} che +è un vettore di strutture \var{iovec}, la cui lunghezza è specificata da +\param{count}. Ciascuna struttura dovrà essere inizializzata per +opportunamente per indicare i vari buffer da/verso i quali verrà eseguito il +trasferimento dei dati. Essi verranno letti (o scritti) nell'ordine in cui li +si sono specificati nel vattore \var{vector}. \subsection{File mappati in memoria} @@ -832,23 +825,36 @@ Essi verranno letti (o scritti) nell'ordine in cui li si sono specificati. Una modalità alternativa di I/O, che usa una interfaccia completamente diversa rispetto a quella classica vista in \capref{cha:file_unix_interface}, è il -cosiddetto \textit{memory-mapped I/O}, che attraverso il meccanismo della +cosiddetto \textit{memory-mapped I/O}, che, attraverso il meccanismo della \textsl{paginazione}\index{paginazione} usato dalla memoria virtuale (vedi -\secref{sec:proc_mem_gen}) permette di \textsl{mappare} il contenuto di un -file in una sezione dello spazio di indirizzi del processo. +\secref{sec:proc_mem_gen}), permette di \textsl{mappare} il contenuto di un +file in una sezione dello spazio di indirizzi del processo. Il meccanismo è +illustrato in \figref{fig:file_mmap_layout}; una sezione del file viene +riportata direttamente nello spazio degli indirizzi del programma. Tutte le +operazioni su questo zona verranno riportate indietro sul file dal meccanismo +della memoria virtuale che trasferirà il contenuto di quel segmento sul file +invece che nella swap. + +\begin{figure}[htb] + \centering + \includegraphics[width=10cm]{img/mmap_layout} + \caption{Disposizione della memoria di un processo quando si esegue la + mappatuara in memoria di un file.} + \label{fig:file_mmap_layout} +\end{figure} Tutto questo comporta una notevole semplificazione delle operazioni di I/O, in quanto non sarà più necessario utilizzare dei buffer intermedi su cui appoggiare i dati da traferire, ma questi potranno essere acceduti -direttamente dalla sezione di memoria; inoltre questa interfaccia -è più efficiente delle usuali funzioni di I/O, in quanto permette di caricare -in memoria solo le parti del file che sono effettivamente usate ad un dato +direttamente nella sezione di memoria mappata; inoltre questa interfaccia è +più efficiente delle usuali funzioni di I/O, in quanto permette di caricare in +memoria solo le parti del file che sono effettivamente usate ad un dato istante. Infatti, dato che l'accesso è fatto direttamente attraverso la memoria virtuale, la sezione di memoria mappata su cui si opera sarà a sua volta letta o scritta sul file una pagina alla volta e solo per le parti effettivamente -usate, il tutto in maniera completamente trasparente al processo; l'acceso +usate, il tutto in maniera completamente trasparente al processo; l'accesso alle pagine non ancora caricate avverrà allo stesso modo con cui vengono caricate in memoria le pagine che sono state salvate sullo swap. @@ -858,9 +864,9 @@ vengono scritte sulla swap; questo consente di accedere ai file su dimensioni il cui solo limite è quello dello spazio di indirizzi disponibile, e non della memoria su cui possono esserne lette delle porzioni. -L'interfaccia prevede varie funzioni per la gestione del \textit{memory - mapping}, la prima di queste è \func{mmap}, che esegue la mappatura in -memoria un file; il suo prototipo è: +L'interfaccia prevede varie funzioni per la gestione del \textit{memory mapped + I/O}, la prima di queste è \func{mmap}, che serve ad eseguire la mappatura +in memoria di un file; il suo prototipo è: \begin{functions} \headdecl{unistd.h} @@ -976,8 +982,8 @@ come maschera binaria ottenuta dall'OR di uno o pi \macro{MAP\_EXECUTABLE}& Ignorato. \\ \macro{MAP\_NORESERVE} & Si usa con \macro{MAP\_PRIVATE}. Non riserva delle pagine di swap ad uso del meccanismo di - \textit{copy on write} per mantenere le modifiche - fatte alla regione mappata, in + \textit{copy on write} per mantenere le + modifiche fatte alla regione mappata, in questo caso dopo una scrittura, se non c'è più memoria disponibile, si ha l'emissione di un \macro{SIGSEGV}. \\ @@ -1020,14 +1026,15 @@ ricordi quanto esposto in \secref{sec:file_vfs_work}), ma esistono anche casi (un esempio è l'interfaccia ponte PCI-VME del chip Universe) di dispositivi che sono utilizzabili praticamente solo con questa interfaccia. -Passando attraverso una \func{fork} i file mappati in memoria vengono -ereditati in maniera trasparente dal processo figlio, mantenendo gli stessi -attributi avuti nel padre; così se si è usato \macro{MAP\_SHARED} padre e -figlio accederanno allo stesso file in maniera condivisa, mentre se si è usato -\macro{MAP\_PRIVATE} ciascuno di essi manterrà una sua versione privata -indipendente. Non c'è invece nessun passaggio attraverso una \func{exec}, dato -che quest'ultima sostituisce tutto lo spazio degli indirizzi di un processo -con quello di un nuovo programma. +Dato che, passando attraverso una \func{fork}, lo spazio di indirizzi viene +sempre copiato, i file mappati in memoria verranno ereditati in maniera +trasparente dal processo figlio, mantenendo gli stessi attributi avuti nel +padre; così se si è usato \macro{MAP\_SHARED} padre e figlio accederanno allo +stesso file in maniera condivisa, mentre se si è usato \macro{MAP\_PRIVATE} +ciascuno di essi manterrà una sua versione privata indipendente. Non c'è +invece nessun passaggio attraverso una \func{exec}, dato che quest'ultima +sostituisce tutto lo spazio degli indirizzi di un processo con quello di un +nuovo programma. Quando si effettua la mappatura di un file vengono pure modificati i tempi ad esso associati (si ricordi quanto esposto in \secref{sec:file_file_times}). Il @@ -1140,8 +1147,8 @@ pagine contenute (anche parzialmente) nell'intervallo indicato, verr Indicare un intervallo che non contiene pagine mappate non è un errore. Alla conclusione del processo, ogni pagina mappata verrà automaticamente -rilasciata, mentre la chiusura del file descriptor non ha alcun effetto sulla -mappatura della memoria. +rilasciata, mentre la chiusura del file descriptor usato per effettuare la +mappatura in memoria non ha alcun effetto sulla stessa. \section{Il file locking} diff --git a/html/index.html b/html/index.html index 33fbd2c..a54c1d8 100644 --- a/html/index.html +++ b/html/index.html @@ -96,7 +96,7 @@

Ma se trovare della buona documentazione libera, specie per quanto riguarda i programmi che girano sul sistema GNU/Linux, è ormai relativamente facile, la produzione di buoni testi - didattici è ancora molto limitata, soprattutto se li si cerca + didattici è ancora molto limitata, soprattutto se li si cercano in lingua italiana.

GaPiL è un tentativo di scrivere un manuale di @@ -120,14 +120,40 @@ - 3 - luglio - 2002 -
- Prima versione del sito, con rilascio della prima versione di - GaPiL in un HTML decente.

- 22 - luglio - 2002
- Nuova versione, aggiunte su I/O avanzato, IPC, segnali - real-time. + 3 - luglio - 2002
Prima versione del sito, con + rilascio della prima versione di GaPiL in un HTML passabile. +
+ Sono in versione preliminare, ma ricontrollati e di qualità + accettabile, i capitoli dal primo al nono: introduzione, + gestione dei processi, interfacce di base per i file e per il + controllo dei parametri del sistema, gestione dei segnali. Sono + da ricontrollare, ma di qualità decente, i capitoli dal + tredicesimo al sedicesimo: reti e socket elementari (il + sedicesimo capitolo è incopleto). Sono in corso di stesura, e + pertanto di qualità non classificabile (che può oscillare fra la + bozza non rivista ed il semplice elenco degli argomenti) gli + altri capitoli. +
+ 321 pagine +

+

+ 22 - luglio - 2002
Aggiornamento: iniziata la + stesura del capitolo sull'I/O avanzato. Completata la sezione su + pipe e fifo (in versione preliminare) inziate le sezioni su I/O + asincrono ed una sezione aggiuntiva sui segnali real-time nel + relativo capitolo. +
+ 333 pagine +

+

+ 22 - agosto - 2002
Aggiornamento: completata la + prima stesura delle sezioni relative all'I/O asincrono ed ai + segnali real-time, iniziata la stesura della sezione sul memory + mapped I/O. +
+ 341 pagine +

diff --git a/ipc.tex b/ipc.tex index 536d096..3bf821c 100644 --- a/ipc.tex +++ b/ipc.tex @@ -371,26 +371,27 @@ approccio diverso. Una possibilit programma, \cmd{epstopsf}, per convertire in PDF un file EPS (che può essere generato da \cmd{barcode} utilizzando lo switch \cmd{-E}). Utilizzando un PDF al posto di un EPS \cmd{gs} esegue la conversione rispettando le dimensioni -originarie del codice a barre e produce un JPEG delle dimensioni adeguate. - -Questo però ci porta a scontrarci con una caratteristica peculiare delle pipe, -che a prima vista non è evidente. Per poter effettuare la conversione di un -PDF infatti è necessario, per la struttura del formato, dover eseguire delle -\func{lseek} sul file da convertire; se si esegue \cmd{gs} su un file regolare -non ci sono problemi, ma una pipe però è rigidamente sequenziale, ed il -tentativo di eseguire detta operazione su una pipe comporta l'immediato -fallimento con un errore di \macro{ESPIPE}. Questo ci dice che in generale la -concatenazione di vari programmi funzionerà soltanto quando tutti prevedono -una lettura sequenziale del loro input. - -Per questo motivo si è dovuto utilizzare una strada diversa, che prevede la -conversione attraverso \cmd{gs} del PS in un altro formato intermedio, il -PPM,\footnote{il \textit{Portable PixMap file format} è un formato usato - spesso come formato intermedio per effettuare conversioni, è estremamente - inefficiente, ma molto facile da manipolare dato che usa caratteri ASCII per - memorizzare le immagini.} dal quale poi si può ottenere un'immagine di -dimensioni corrette attraverso vari programmi di manipolazione (\cmd{pnmcrop}, -\cmd{pnmmargin}) che può essere infine trasformata in PNG (con \cmd{pnm2png}). +originarie del codice a barre e produce un JPEG di dimensioni corrette. + +Questo approccio però non funziona, per via di una delle caratteristiche +principali delle pipe. Per poter effettuare la conversione di un PDF infatti è +necessario, per la struttura del formato, potersi spostare (con \func{lseek}) +all'interno del file da convertire; se si eseguela conversione con \cmd{gs} su +un file regolare non ci sono problemi, una pipe però è rigidamente +sequenziale, e l'uso di \func{lseek} su di essa fallisce sempre con un errore +di \macro{ESPIPE}, rendendo impossibile la conversione. Questo ci dice che in +generale la concatenazione di vari programmi funzionerà soltanto quando tutti +prevedono una lettura sequenziale del loro input. + +Per questo motivo si è dovuto utilizzare un procedimento diverso, eseguendo +prima la conversione (sempre con \cmd{gs}) del PS in un altro formato +intermedio, il PPM,\footnote{il \textit{Portable PixMap file format} è un + formato usato spesso come formato intermedio per effettuare conversioni, è + infatti molto facile da manipolare, dato che usa caratteri ASCII per + memorizzare le immagini, anche se per questo è estremamente inefficiente.} +dal quale poi si può ottenere un'immagine di dimensioni corrette attraverso +vari programmi di manipolazione (\cmd{pnmcrop}, \cmd{pnmmargin}) che può +essere infine trasformata in PNG (con \cmd{pnm2png}). In questo caso però occorre eseguire in sequenza ben quattro comandi diversi, inviando l'output di ciascuno all'input del successivo, per poi ottenere il @@ -469,7 +470,7 @@ Alla fine tutto quello che resta da fare primo processo della catena, che nel caso è \cmd{barcode}, e scrivere (\texttt{\small 23}) la stringa del codice a barre sulla pipe, che è collegata al suo standard input, infine si può eseguire (\texttt{\small 24--27}) un -ciclo, che chiuda, nell'ordine inverso rispetto a quello in cui le si sono +ciclo che chiuda, nell'ordine inverso rispetto a quello in cui le si sono create, tutte le pipe create con \func{pclose}. @@ -509,44 +510,44 @@ nel qual caso l'apertura del capo in lettura avr l'altro capo è aperto, mentre l'apertura del capo in scrittura restituirà l'errore di \macro{ENXIO} fintanto che non verrà aperto il capo in lettura. -In Linux\footnote{lo standard POSIX lascia indefinito questo comportamento.} è -possibile aprire le fifo anche in lettura/scrittura, operazione che avrà -sempre successo immediato qualunque sia la modalità di apertura (bloccante e -non bloccante); questo può essere utilizzato per aprire comunque una fifo in -scrittura anche se non ci sono ancora processi il lettura; è possibile anche -usare la fifo all'interno di un solo processo, nel qual caso però occorre -stare molto attenti alla possibili deadlock.\footnote{se si cerca di leggere - da una fifo che non contiene dati si avrà un deadlock immediato, dato che il - processo si blocca e non potrà quindi mai eseguire le funzioni di - scrittura.} +In Linux è possibile aprire le fifo anche in lettura/scrittura,\footnote{lo + standard POSIX lascia indefinito il comportamento in questo caso.} +operazione che avrà sempre successo immediato qualunque sia la modalità di +apertura (bloccante e non bloccante); questo può essere utilizzato per aprire +comunque una fifo in scrittura anche se non ci sono ancora processi il +lettura; è possibile anche usare la fifo all'interno di un solo processo, nel +qual caso però occorre stare molto attenti alla possibili +deadlock.\footnote{se si cerca di leggere da una fifo che non contiene dati si + avrà un deadlock immediato, dato che il processo si blocca e non potrà + quindi mai eseguire le funzioni di scrittura.} Per la loro caratteristica di essere accessibili attraverso il filesystem, è piuttosto frequente l'utilizzo di una fifo come canale di comunicazione nelle -situazioni un processo deve ricevere informazioni dagli altri. In questo caso -è fondamentale che le operazioni di scrittura siano atomiche; per questo si -deve sempre tenere presente che questo è vero soltanto fintanto che non si -supera il limite delle dimensioni di \macro{PIPE\_BUF} (si ricordi quanto -detto in \secref{sec:ipc_pipes}). - -A parte il precedente, che resta probabilmente il più comune, Stevens riporta -in \cite{APUE} altre due casistiche principali per l'uso delle fifo: +situazioni un processo deve ricevere informazioni da altri. In questo caso è +fondamentale che le operazioni di scrittura siano atomiche; per questo si deve +sempre tenere presente che questo è vero soltanto fintanto che non si supera +il limite delle dimensioni di \macro{PIPE\_BUF} (si ricordi quanto detto in +\secref{sec:ipc_pipes}). + +A parte il caso precedente, che resta probabilmente il più comune, Stevens +riporta in \cite{APUE} altre due casistiche principali per l'uso delle fifo: \begin{itemize} \item Da parte dei comandi di shell, per evitare la creazione di file temporanei quando si devono inviare i dati di uscita di un processo sull'input di parecchi altri (attraverso l'uso del comando \cmd{tee}). -\item Come canale di comunicazione fra un client ed un server (il modello +\item Come canale di comunicazione fra client ed server (il modello \textit{client-server} è illustrato in \secref{sec:net_cliserv}). \end{itemize} -Nel primo caso quello che si fa è creare tante pipe quanti sono i processi a -cui i vogliono inviare i dati, da usare come standard input per gli stessi; una -volta che li si saranno posti in esecuzione ridirigendo lo standard input si -potrà eseguire il processo iniziale replicandone, con il comando \cmd{tee}, -l'output sulle pipe. +Nel primo caso quello che si fa è creare tante fifo, da usare come standard +input, quanti sono i processi a cui i vogliono inviare i dati, questi ultimi +saranno stati posti in esecuzione ridirigendo lo standard input dalle fifo, si +potrà poi eseguire il processo che fornisce l'output replicando quest'ultimo, +con il comando \cmd{tee}, sulle varie fifo. Il secondo caso è relativamente semplice qualora si debba comunicare con un -processo alla volta (nel qual caso basta usare due pipe, una per leggere ed +processo alla volta (nel qual caso basta usare due fifo, una per leggere ed una per scrivere), le cose diventano invece molto più complesse quando si vuole effettuare una comunicazione fra il server ed un numero imprecisato di client; se il primo infatti può ricevere le richieste attraverso una fifo @@ -567,26 +568,25 @@ sistema generale infatti l'interfaccia delle fifo non è adatta a risolvere questo tipo di problemi, che possono essere affrontati in maniera più semplice ed efficace o usando i \textit{socket}\index{socket} (che tratteremo in dettaglio a -partire da \capref{cha:socket_intro}) o ricorrendo a diversi meccanismi di -comunicazione, come quelli che esamineremo in \secref{sec:ipc_sysv}. +partire da \capref{cha:socket_intro}) o ricorrendo a meccanismi di +comunicazione diversi, come quelli che esamineremo in seguito. \section{La comunicazione fra processi di System V} \label{sec:ipc_sysv} -Benché le pipe (e le fifo) siano ancora ampiamente usate, esse presentano -numerosi limiti, il principale dei quali è che il meccanismo di comunicazione -è rigidamente sequenziale; per questo una situazione in cui un processo scrive -qualcosa che molti altri devono poter leggere non può essere implementata in -maniera semplice con una pipe. +Benché le pipe e le fifo siano ancora ampiamente usate, esse scontano il +limite fondamentale che il meccanismo di comunicazione che forniscono è +rigidamente sequenziale: una situazione in cui un processo scrive qualcosa che +molti altri devono poter leggere non può essere implementata con una pipe. -Per superare questi limiti nello sviluppo di System V vennero introdotti una -serie di nuovi oggetti di comunicazione e relative interfacce di -programmazione in grado di garantire una maggiore flessibilità; in questa -sezione esamineremo quello che viene ormai chiamato il \textsl{Sistema di - comunicazione inter-processo} di System V, (o \textit{System V IPC - (Inter-Process Comunication)}. +Per questo nello sviluppo di System V vennero introdotti una serie di nuovi +oggetti per la comunicazione fra processi ed una nuova interfaccia di +programmazione, che fossero in grado di garantire una maggiore flessibilità; +in questa sezione esamineremo quello che viene ormai chiamato il +\textsl{Sistema di comunicazione inter-processo} di System V, (o +\textit{System V IPC (Inter-Process Comunication)}. @@ -596,29 +596,26 @@ sezione esamineremo quello che viene ormai chiamato il \textsl{Sistema di La principale caratteristica del sistema di IPC di System V è quella di essere basato su oggetti permanenti che risiedono nel kernel. Questi, a differenza di quanto avviene per i file descriptor, non mantengono un contatore dei -riferimenti, pertanto non vengono cancellati dal sistema una volta che non -sono più in uso. Questo comporta che, al contrario di quanto avviene per pipe -e fifo, la memoria allocata per questi oggetti non viene rilasciata -automaticamente, ed essi devono essere cancellati esplicitamente, altrimenti -resteranno attivi fintanto che non si riavvia il sistema. +riferimenti, e non vengono cancellati dal sistema una volta che non sono più +in uso. Questo comporta che, al contrario di quanto avviene per pipe e fifo, +la memoria allocata per questi oggetti non viene rilasciata automaticamente, +ed essi devono essere cancellati esplicitamente, altrimenti resteranno attivi +fino al riavvio del sistema. Gli oggetti usati nel System V IPC vengono creati direttamente dal kernel, e -sono accessibili solo specificando il relativo \textsl{identificatore}, che è -il numero progressivo che il kernel gli assengna quanto vengono creati (il -prodedimento è simile a quello con cui si assegna il \acr{pid} dei processi). +sono accessibili solo specificando il relativo \textsl{identificatore}. Questo +è il numero progressivo che il kernel assengna a ciascuno di questi oggetti +quanto vengono creati (il prodedimento è simile a quello con cui si assegna il +\acr{pid} ai processi). L'identificatore è in genere restituito dalle funzioni che creano l'oggetto, nasce quindi il problema di come processi diversi possono accedere allo stesso oggetto. Per far questo a ciascuno di essi viene anche associata una \textsl{chiave}, che può essere indicata in fasi di creazione. Usando la stessa chiave due processi diversi potranno ricavare l'identificatore -associato ad un oggetto e accedervi entrambi. - -Questa caratteristica mostra il primo dei problemi associati al sistema di IPC -di System V. Un secondo problema riguarda le modalità per l'accesso a questi -oggetti. - +associato ad un oggetto e accedervi entrambi. +Il problema che sorge a questo punto è come due processi diversi possono \subsection{Code di messaggi} @@ -647,7 +644,8 @@ condivisa. Lo standard POSIX.1b ha introdotto dei nuovi meccanismi di comunicazione, rifacendosi a quelli di System V, introducendo una nuova interfaccia che -evitasse i principali problemi evidenziati in ... +evitasse i principali problemi evidenziati in coda a +\secref{sec:ipc_sysv_generic}. diff --git a/process.tex b/process.tex index 9f61d88..ca92e15 100644 --- a/process.tex +++ b/process.tex @@ -395,7 +395,7 @@ seguenti segmenti: \begin{figure}[htb] \centering \includegraphics[width=5cm]{img/memory_layout} - \caption{Disposizione tipica dei segmenti di memoria di un processo} + \caption{Disposizione tipica dei segmenti di memoria di un processo.} \label{fig:proc_mem_layout} \end{figure}