Deciso, si prosegue con le ipc
authorSimone Piccardi <piccardi@gnulinux.it>
Sat, 1 Jun 2002 20:33:31 +0000 (20:33 +0000)
committerSimone Piccardi <piccardi@gnulinux.it>
Sat, 1 Jun 2002 20:33:31 +0000 (20:33 +0000)
fileadv.tex
fileunix.tex
gapil.tex
ipc.tex
signal.tex

index 6737554..fa41648 100644 (file)
-\chapter{I/O avanzato}
+\chapter{La gestione avanzata dei file}
 \label{cha:file_advanced}
 
-In questo capitolo affronteremo le tematiche della gestione avanzata delle
-funzioni di input/ouput, prenderemo in esame il \textit{file locking}, la
-gestione dell'input/output da più file, per concludere con la gestione dei
-file mappati in memoria.
+In questo capitolo affronteremo le tematiche relative alla gestione avanzata
+dei file, che non sono state trattate in \capref{cha:file_unix_interface},
+dove ci si è limitati ad una panoramica delle funzioni base. In particolare
+tratteremo delle funzioni di input/output avanzato e del \textit{file
+  locking}.
 
 
-\section{L'I/O avanzato}
+\section{Le funzioni di I/O avanzato}
 \label{sec:file_advanced_io}
 
-Uno dei problemi che ci si trova ad affrontare con le funzioni ordinarie
-trattate in \capref{cha:file_unix_interface} è quello in cui si devono
-eseguire su più di un file descriptor delle operazioni che possono bloccarsi:
-il problema è che mentre si è bloccati su un file su di un'altro potrebbero
-essere presenti dati da leggere.
-
-In questa sezione vedremo come si possono affrontare queste problematiche,
-quali sono le soluzioni possibili e quali i meccanismi il kernel e le librerie
-ci mettono a disposizione.
+In questa sezione esamineremo le funzioni che permettono una gestione più
+sofisticata dell'I/O su file, a partire da quelle che permettono di gestire
+l'accesso contemporaneo a più file, per concludere con la gestione dell'I/O
+mappato in memoria.
 
 
 \subsection{La modalità di I/O \textsl{non-bloccante}}
 \label{sec:file_noblocking}
 
-Una prima soluzione per evitare di bloccarsi nelle operazioni di I/O è quella
-di utilizzare la modalità \textsl{non-bloccante}. Abbiamo visto in
-\secref{sec:sig_gen_beha}, affrontando la suddivisione fra \textit{fast} e
-\textit{slow} system call, che in certi casi le funzioni di I/O possono
-bloccarsi indefinitamente.\footnote{si ricordi però che questo può accadere
-  solo per le pipe, i socket ed alcuni file di dispositivo; sui file normali
-  le funzioni di lettura e scrittura ritornano sempre subito.} 
-In particolare le operazioni di lettura possono bloccarsi quando non ci sono
-dati disponibili sul descrittore su cui si sta operando.
+Abbiamo visto in \secref{sec:sig_gen_beha}, affrontando la suddivisione fra
+\textit{fast} e \textit{slow} system call, che in certi casi le funzioni di
+I/O possono bloccarsi indefinitamente.\footnote{si ricordi però che questo può
+  accadere solo per le pipe, i socket ed alcuni file di dispositivo; sui file
+  normali le funzioni di lettura e scrittura ritornano sempre subito.}  Ad
+esempio le operazioni di lettura possono bloccarsi quando non ci sono dati
+disponibili sul descrittore su cui si sta operando.
+
+Uno dei problemi più comuni che ci si trova ad affrontare che non può essere
+risolto con le funzioni base trattate in \capref{cha:file_unix_interface} è
+quello in cui si devono eseguire su più di un file descriptor delle operazioni
+che possono bloccarsi: il problema è che mentre si è bloccati su uno di questi
+file su di un'altro potrebbero essere presenti dei dati.
 
 Abbiamo già accennato in \secref{sec:file_open} che è possibile prevenire
-questo tipo di comportamento aprendo il file in modalità non bloccante,
-specificando il flag \macro{O\_NONBLOCK}. In questo caso le funzioni che si
-sarebbero bloccate ritornano immediatamente restituendo l'errore
+questo tipo di comportamento aprendo un file in modalità
+\textsl{non-bloccante}, specificando il flag \macro{O\_NONBLOCK} alla chiamata
+di \func{open}. In questo caso le funzioni di input/output che altrimenti si
+sarebbero bloccate ritornano immediatamente, restituendo l'errore
 \macro{EAGAIN}.
 
-L'utilizzo di questa modalità di I/O permette allora di risolvere il problema 
+L'utilizzo di questa modalità di I/O permette allora di risolvere il problema
+controllando a turno i vari file descriptor, in un ciclo in cui si ripete
+l'accesso fintanto che esso non viene garantito.  Ovviamente questa tecnica,
+detta \textit{polling}, è estremamente inefficiente: si tiene costantemente
+impiegata la CPU solo per eseguire in continuazione delle system call che
+nella gran parte dei casi falliranno.
+
+Per questo motivo, quando come vedremo in dettaglio in
+\secref{sec:file_multiplexing}, il sistema fornisce delle funzioni apposite
+che permettono di aggirare questo problema, permettendo di attendere fino alla
+disponibilità di un accesso; per usarle però è comunque comunque necessario
+utilizzare la modalità di I/O non bloccante.
+
+\subsection{Le funzioni \func{poll} e \func{select}}
+\label{sec:file_multiplexing}
 
 
 %\section{I/O asincrono}
 %\label{sec:file_asynchronous}
 
 %Non supportato in Linux, in BSD e SRv4 c'è, ma usando il segnale \macro{SIGIO}
-%per indicare che i dati sono disponibili, può essere usato in maniera semplice
-%con un solo file per processo (altrimenti non sarebbe più possibile
-%distinguere da quale file proviene l'attività che ha causato l'emissione del
-%segnale).
+%per indicare che i dati sono disponibili, 
 
 \subsection{L'I/O asincrono}
 \label{sec:file_asyncronous_io}
 
+Una modalità alternativa all'uso dell'I/O non bloccante è quella di fare
+ricorso all'I/O asincrono. Abbiamo accennato in \secref{sec:file_open} che è
+possibile, attraverso l'uso del flag \macro{O\_ASYNC}, aprire un file in
+modalità asincrona, così come è possibile settare questo flag attraverso l'uso
+di \func{fcntl}.
+
+In tal caso il sistema genera un segnale \macro{SIGIO} tutte le volte che sono
+presenti dei dati in input sul file.
 
 
-\subsection{Le funzioni \func{poll} e \func{select}}
-\label{sec:file_multiplexing}
 
+Un dei problemi che si presentavano con le prime implementazioni di questa
+modalità di I/O è che essa poteva essere usata in maniera semplice con un solo
+file per processo, dato che altrimenti non sarebbe stato distinguere da quale
+file proviene l'attività che ha causato l'emissione del segnale. 
 
 
 
 
 
-\section{File locking}
+\subsection{File mappati in memoria}
+\label{sec:file_memory_map}
+
+
+\subsection{I/O multiplo}
+\label{sec:file_multiple_io}
+
+
+
+\section{Il file locking}
 \label{sec:file_locking}
 
 In \secref{sec:file_sharing} abbiamo preso in esame le mosalità in cui un
-sistema unix-like gestisce la condivisione dei file. In quell'occasione si è
-visto come, con l'eccezione dei file aperti in \textit{append mode}, quando
-più processi scrivono contemporaneamente sullo stesso file non è possibile
-determinare la sequenza in cui essi opereranno.
+sistema unix-like gestisce la condivisione dei file da parte di processi
+diversi. In quell'occasione si è visto come, con l'eccezione dei file aperti
+in \textit{append mode}, quando più processi scrivono contemporaneamente sullo
+stesso file non è possibile determinare la sequenza in cui essi opereranno.
 
 Questo causa la possibilità di race condition; in generale le situazioni più
 comuni sono due: l'interazione fra un processo che scrive e altri che leggono,
@@ -82,11 +113,11 @@ in maniera imprevedebile il loro output sul file.
 
 In tutti questi casi il \textit{file locking} è la tecnica che permette di
 evitare le race condition, attraverso una serie di funzioni che permettono di
-bloccare l'accesso al file da parte di altri processi così da evitare le
+bloccare l'accesso al file da parte di altri processi, così da evitare le
 sovrapposizioni, e garantire la atomicità delle operazioni di scrittura.
 
 
-\subsection{Il \textit{advisory locking}}
+\subsection{L'\textit{advisory locking}}
 \label{sec:file_record_locking}
 
 La prima modalità di file locking che è stata implementata nei sistemi
@@ -100,14 +131,11 @@ esiste una condizione di blocco per l'accesso ai file.
 \subsection{Il \textit{mandatory locking}}
 \label{sec:file_mand_locking}
 
-Il \textit{mandatory locking} è una opzione introdotta inizialmente in SVR4, 
+Il \textit{mandatory locking} è una opzione introdotta inizialmente in SVr4, 
 
 
 
 
-\section{File mappati in memoria}
-\label{sec:file_memory_map}
-
 
 
 %%% Local Variables: 
index 7f970c7..a8a7d78 100644 (file)
@@ -271,9 +271,10 @@ sempre il file descriptor con il valore pi
     le fifo e per alcuni file di dispositivo. \\
     \macro{O\_NDELAY} & in Linux\footnotemark\ è sinonimo di 
     \macro{O\_NONBLOCK}.\\
-    \macro{O\_ASYNC} & apre il file per l'input/output in modalità
-    asincrona. Quando è settato viene generato un segnale di \macro{SIGIO}
-    tutte le volte che è disponibile dell'input sul file. \\
+    \macro{O\_ASYNC} & apre il file per l'I/O in modalità
+    asincrona (vedi \secref{sec:file_asyncronous_io}). Quando è settato viene
+    generato il segnale \macro{SIGIO} tutte le volte che sono disponibili
+    dati in input sul file. \\ 
     \macro{O\_SYNC} & apre il file per l'input/output sincrono, ogni
     \func{write} bloccherà fino al completamento della scrittura di tutti dati
     sul sull'hardware sottostante.\\
@@ -1007,11 +1008,13 @@ valori 
   segnali \macro{SIGIO} e \macro{SIGURG} per gli eventi associati al file
   descriptor \var{fd}.  I process group sono settati usando valori negativi.
 \item[\macro{F\_GETSIG}] restituisce il segnale mandato quando ci sono dati
-  disponibili in input sul file descriptor. Il valore 0 indica il default (che
-  è \macro{SIGIO}), un valore diverso da zero indica il segnale richiesto,
-  (che può essere lo stesso \macro{SIGIO}), nel qual caso al manipolatore del
-  segnale, se installato con \macro{SA\_SIGINFO}, vengono rese disponibili
-  informazioni ulteriori informazioni.
+  disponibili in input su un file descriptor aperto o settato in I/O
+  asincrono. Il valore 0 indica il default (che è \macro{SIGIO}), un valore
+  diverso da zero indica il segnale richiesto, (che può essere lo stesso
+  \macro{SIGIO}).\footnote{in questo caso al manipolatore del segnale, se
+    installato come \var{sa\_sigaction} con \macro{SA\_SIGINFO}, vengono rese
+    disponibili informazioni ulteriori informazioni (vedi
+    \secref{sec:sig_sigaction} e \secref{sec:file_asyncronous_io})}.
 \item[\macro{F\_SETSIG}] setta il segnale da inviare quando diventa possibile
   effettuare I/O sul file descriptor. Il valore zero indica il default
   (\macro{SIGIO}), ogni altro valore permette di rendere disponibile al
index 06791aa..dc2c43a 100644 (file)
--- a/gapil.tex
+++ b/gapil.tex
 \include{filestd}
 \include{system}
 \include{signal}
+\include{ipc}
 \include{fileadv}
 \include{session}
-\include{ipc}
 \include{network}
 \include{socket}
 \include{elemtcp}
diff --git a/ipc.tex b/ipc.tex
index 6c1041e..24ec8f4 100644 (file)
--- a/ipc.tex
+++ b/ipc.tex
@@ -3,16 +3,17 @@
 
 
 Uno degli aspetti fondamentali della programmazione in un sistema unix-like è
-la comunicazione fra processi. In questo capitolo affronteremo solo alcuni dei
+la comunicazione fra processi. In questo capitolo affronteremo solo i
 meccanismi più elementari che permettono di mettere in comunicazione processi
 diversi, come quelli tradizionali che coinvolgono \textit{pipe} e
 \textit{fifo} e i meccanismi di intercomunicazione di System V.
 
-Esistono pure sistemi più complessi ed evoluti come le RPC (\textit{Remote
-  Procedure Calls}) e CORBA (\textit{Common Object Request Brocker
-  Architecture}) che non saranno affrontati qui. Inoltre tratteremo nei
-capitoli successivi tutta la problematica relativa alla comunicazione
-attraverso la rete.
+Tralasceremo invece tutte le problematiche relative alla comunicazione
+attraverso la rete (e le relative interfacce) che saranno affrontate in gran
+dettaglio in un secondo tempo.  Non affronteremo invece meccanismi più
+complessi ed evoluti come le RPC (\textit{Remote Procedure Calls}) e CORBA
+(\textit{Common Object Request Brocker Architecture}) che in genere sono
+implementati con un ulteriore livello sopra i meccanismi elementari.
 
 
 
@@ -27,18 +28,36 @@ funzioni che ne gestiscono l'uso e le varie forme in cui si 
 \subsection{Le \textit{pipe} standard}
 \label{sec:ipc_pipes}
 
-Le \textit{pipe} nascono sostanzialmente con Unix, e sono il primo, e più
-comunemente usato, meccanismo di comunicazione fra processi. Esse sono un file
-speciale in cui un processo scrive ed un altro legge. Si viene così a
-costituire un canale di comunicazione fra i due processi, nella forma di un
-\textsl{tubo} (da cui il nome) in cui uno immette dati che arriveranno
-all'altro. 
-
-Perché questo accada però, e questo è il principale limite nell'uso delle
-\textit{pipe}, è necessario che questi processi possano condividere il file
-descriptor della \textit{pipe}; per questo essi devono comunque derivare da
-uno stesso processo padre, o, più comunemente, essere nella relazione
-padre/figlio.
+Le \textit{pipe} nascono sostanzialmente con Unix, e sono il primo, ed uno dei
+più usati, meccanismi di comunicazione fra processi. Si tratta in sostanza uno
+speciale tipo di file\footnote{più precisamente un file descriptor; le pipe
+  sono create dal kernel e non risiedono su disco.} in cui un processo scrive
+ed un altro legge. Si viene così a costituire un canale di comunicazione fra i
+due processi, nella forma di un \textsl{tubo} (da cui il nome) in cui uno dei
+processi immette dati che poi arriveranno all'altro.
+
+Perché questo accada però, e questo è il principale\footnote{Stevens riporta
+  in APUE come limite anche il fatto che la comunicazione è unidirezionale, in
+  realtà questo è un limite facilemente risolvibile usando una coppia di
+  \textit{pipe}.} e limite nell'uso delle \textit{pipe}, è necessario che
+questi processi possano condividere il file descriptor della \textit{pipe};
+per questo essi devono comunque derivare da uno stesso processo padre, o, più
+comunemente, essere nella relazione padre/figlio.
+
+La funzione che permette di creare una \textit{pipe} è appunto \func{pipe}; il
+suo prototipo è:
+\begin{prototype}{unistd.h}
+{int pipe(int filedes[2])} 
+  
+Crea una coppia di file descriptor associati ad una \textit{pipe}.
+  
+  \bodydesc{La funzione restituisce zero in caso di successo e -1 per un
+    errore, nel qual caso \var{errno} potrà assumere i valori \macro{EMFILE},
+    \macro{ENFILE} e \macro{EFAULT}.}
+\end{prototype}
+
+La funzione restituisce una coppia di file descriptor nell'array
+\param{filedes}; il primo aperto in lettura ed il secondo in scrittura
 
 
 
@@ -58,17 +77,18 @@ per le comunicazioni senza dovere per forza essere in relazione diretta.
 \label{sec:ipc_sysv}
 
 Per ovviare ai vari limiti dei meccanismo tradizionale di comunicazione fra
-processi basato sulle \textit{pipe}, nello sviluppo di System V vennero
-introdotti una serie di nuovi oggetti che garantissero una maggiore
-flessibilità; in questa sezione esamineremo quello che viene ormai chiamato il
-\textit{System V Inter Process Comunication system}, più comunemente noto come 
-\textit{SystemV IPC}. 
+processi visto in \secref{sec:ipc_unix}, nello sviluppo di System V vennero
+introdotti una serie di nuovi oggetti e relative interdacce che garantissero
+una maggiore flessibilità; in questa sezione esamineremo quello che viene
+ormai chiamato il \textit{System V Inter-Process Comunication System}, più
+comunemente noto come \textit{SystemV IPC}.
  
+
 \subsection{Code di messaggi}
 \label{sec:ipc_messque}
 
 Il primo oggetto introdotto dal \textit{SystemV IPC} è quello delle code di
-messaggi. 
+messaggi.
 
 \subsection{Semafori}
 \label{sec:ipc_semaph}
index 411538c..519cf44 100644 (file)
@@ -1801,9 +1801,45 @@ indicate dai campi \var{sa\_handler} e \var{sa\_sigaction}; esse devono essere
 usate in maniera alternativa (in certe implementazioni questi vengono
 specificati come \ctyp{union}): la prima è quella classica usata anche con
 \func{signal}, la seconda permette invece di usare un manipolatore in grado di
-ricevere informazioni più dettagliate dal sistema (ad esempio il tipo di
-errore in caso di \macro{SIGFPE}), attraverso dei parametri aggiuntivi; per i
-dettagli si consulti la man page di \func{sigaction}).
+ricevere informazioni più dettagliate dal sistema, attraverso la struttura
+\var{siginfo\_t}, riportata in \figref{fig:sig_siginfo_t}.
+
+\begin{figure}[!htb]
+  \footnotesize \centering
+  \begin{minipage}[c]{15cm}
+    \begin{lstlisting}[labelstep=0]{}%,frame=,indent=1cm]{}
+siginfo_t {
+    int      si_signo;  /* Signal number */
+    int      si_errno;  /* An errno value */
+    int      si_code;   /* Signal code */
+    pid_t    si_pid;    /* Sending process ID */
+    uid_t    si_uid;    /* Real user ID of sending process */
+    int      si_status; /* Exit value or signal */
+    clock_t  si_utime;  /* User time consumed */
+    clock_t  si_stime;  /* System time consumed */
+    sigval_t si_value;  /* Signal value */
+    int      si_int;    /* POSIX.1b signal */
+    void *   si_ptr;    /* POSIX.1b signal */
+    void *   si_addr;   /* Memory location which caused fault */
+    int      si_band;   /* Band event */
+    int      si_fd;     /* File descriptor */
+}
+    \end{lstlisting}
+  \end{minipage} 
+  \normalsize 
+  \caption{La struttura \var{siginfo\_t}.} 
+  \label{fig:sig_siginfo_t}
+\end{figure}
+Installando un manipolatore di tipo \var{sa\_sigaction} diventa allora
+possibile accedere al risultato restituito attraverso il puntatore a questa
+struttura. Tutti i segnali settano i campi \var{si\_signo}, \var{si\_errno} e
+\var{si\_code}, ed il resto della struttura può essere definito come
+\ctyp{union} ed i valori eventualmente presenti dipendono dal segnale (ad
+esempio può essere il tipo di errore nel caso di \macro{SIGFPE}); vedremo un
+esempio di tutto ciò per \macro{SIGIO} in \secref{sec:file_asyncronous_io},
+per i dettagli degli altri segnali si consulti la man page di
+\func{sigaction}).
 
 Il campo \var{sa\_mask} serve ad indicare l'insieme dei segnali che devono
 essere bloccati durante l'esecuzione del manipolatore, ad essi viene comunque
@@ -2279,26 +2315,6 @@ ripristinata in un successivo \func{siglongjmp}; quest'ultima funzione, a
 parte l'uso di \type{sigjmp\_buf} per \param{env}, è assolutamente identica a
 \func{longjmp}.
 
-\begin{prototype}{signal.h}
-{int sigaltstack(const stack\_t *ss, stack\_t *oss)}
-  
-Installa un nuovo stack per i segnali.
-  
-  \bodydesc{La funzione restituisce zero in caso di successo e -1 per un
-    errore, nel qual caso \var{errno} assumerà i valori:
-
-  \begin{errlist}
-  \item[\macro{ENOMEM}] La dimensione specificata per il nuovo stack è minore
-  di \macro{MINSIGSTKSZ}.
-  \item[\macro{EPERM}] Uno degli indirizzi non è valido.
-  \item[\macro{EFAULT}] Si è cercato di cambiare lo stack alternativo mentre
-  questo è attivo (cioè il processo è in esecuzione su di esso).
-  \item[\macro{EINVAL}] \param{ss} non è nullo e \var{ss\_flags} contiene un
-  valore diverso da zero che non è \macro{SS\_DISABLE}.
-  \end{errlist}}
-\end{prototype}
-
-
 
 %%% Local Variables: 
 %%% mode: latex