X-Git-Url: https://gapil.gnulinux.it/gitweb/?p=gapil.git;a=blobdiff_plain;f=ipc.tex;h=6ecd5b161ddb4e9888c93d8b49a4885e941dd77e;hp=a607aa1f682c800083de6c28a7c96ce2b1f7ed00;hb=e7c1eaebbc012ee182a8d82fc75968969549821d;hpb=3da158e64e344c344c497a98468371a2f01b3c25 diff --git a/ipc.tex b/ipc.tex index a607aa1..6ecd5b1 100644 --- a/ipc.tex +++ b/ipc.tex @@ -124,7 +124,7 @@ consiste nell'inviare l'output di un processo (lo standard output) sull'input di un'altro. Realizzeremo il programma di esempio nella forma di un \textit{CGI}\footnote{Un CGI (\textit{Common Gateway Interface}) è un programma che permette la creazione dinamica di un oggetto da inserire - all'interno di una pagina HTML.} per apache, che genera una immagine JPEG + all'interno di una pagina HTML.} per Apache, che genera una immagine JPEG di un codice a barre, specificato come parametro di input. Un programma che deve essere eseguito come \textit{CGI} deve rispondere a @@ -558,7 +558,7 @@ leggerli, quando i dati inviati sono destinati a loro. Per risolvere questo problema, si può usare un'architettura come quella illustrata in \figref{fig:ipc_fifo_server_arch} in cui i client inviano le richieste al server su una fifo nota mentre le risposte vengono reinviate dal -server a ciascuno di essi su una fifo temporanea creata per l'occazione. +server a ciascuno di essi su una fifo temporanea creata per l'occasione. \begin{figure}[htb] \centering @@ -1229,11 +1229,11 @@ coda. messaggi. \\ \macro{MSGMAX}& 8192& \file{msgmax} & Dimensione massima di un singolo messaggio.\\ - \macro{MSGMNB}&16384& \file{msgmnb} & Dimensione massima di una coda di - messaggi.\\ + \macro{MSGMNB}&16384& \file{msgmnb} & Dimensione massima del contenuto di + una coda.\\ \hline \end{tabular} - \caption{Valori delle costanti associati ai limiti delle code di messaggi.} + \caption{Valori delle costanti associate ai limiti delle code di messaggi.} \label{tab:ipc_msg_limits} \end{table} @@ -1297,7 +1297,7 @@ riportato nella figura. In questa struttura il kernel\footnote{come accennato questo vale fino ai kernel della serie 2.2.x, essa viene usata nei kernel della serie 2.4.x solo per compatibilità in quanto è quella restituita dalle funzioni dell'interfaccia. In \figref{fig:ipc_msgid_sd} sono elencati i - campi significativi definiti in \file{sys/msg.h}, a cui si sono agguinti gli + campi significativi definiti in \file{sys/msg.h}, a cui si sono aggiunti gli ultimi tre campi che sono previsti dalla implementazione originale di System V, ma non dallo standard Unix98.} mantiene le principali informazioni riguardo lo stato corrente della coda. Quando si crea una nuova coda con @@ -1306,10 +1306,22 @@ riguardo lo stato corrente della coda. Quando si crea una nuova coda con \secref{sec:ipc_sysv_access_control}, per quanto riguarda gli altri campi invece: \begin{itemize} -\item i campi \var{msg\_qnum}, \var{msg\_lspid}, \var{msg\_lrpid}, - \var{msg\_stime}, \var{msg\_rtime} sono inizializzati a 0 -\item il campo \var{msg\_ctime} viene settato al tempo corrente -\item il campo \var{msg\_qbytes} al limite di sistema. +\item il campo \var{msg\_qnum}, che esprime il numero di messaggi presenti + sulla coda, viene inizializzato a 0. +\item i campi \var{msg\_lspid} e \var{msg\_lrpid}, che esprimono + rispettivamente il \acr{pid} dell'ultimo processo che ha inviato o ricevuto + un messaggio sulla coda, sono inizializzati a 0. +\item i campi \var{msg\_stime} e \var{msg\_rtime}, che esprimono + rispettivamente il tempo in cui è stato inviato o ricevuto l'ultimo + messaggio sulla coda, sono inizializzati a 0. +\item il campo \var{msg\_ctime} viene inizializzato al tempo corrente. +\item il campo \var{msg\_qbytes} viene inizializzato al valore preimpostato + del sistema (\macro{MSGMNB}). +\item i campi \var{msg\_first} e \var{msg\_last} che esprimono l'indirizzo del + primo e ultimo messaggio sono inizializzati a \macro{NULL} e + \var{msg\_cbytes}, che esprime la dimensione in byte dei messaggi presenti è + inizializzato a zero. Questi campi sono ad uso interno dell'implementazione + e non devono essere utilizzati da programmi in user space). \end{itemize} Una volta creata una coda di messaggi le operazioni di controllo vengono @@ -1345,7 +1357,7 @@ mantenuta all'indirizzo \param{buf}, per la coda specificata dall'identificatore \param{msqid}. Il comportamento della funzione dipende dal valore dell'argomento \param{cmd}, che specifica il tipo di azione da eseguire; i valori possibili sono: -\begin{basedescript}{\desclabelwidth{3cm}\desclabelstyle{\nextlinelabel}} +\begin{basedescript}{\desclabelwidth{2.2cm}\desclabelstyle{\nextlinelabel}} \item[\macro{IPC\_STAT}] Legge le informazioni riguardo la coda nella struttura indicata da \param{buf}. Occorre avere il permesso di lettura sulla coda. @@ -1362,9 +1374,8 @@ eseguire; i valori possibili sono: struttura \var{msqid\_ds} puntata da \param{buf}. Per modificare i valori di \var{msg\_perm.mode}, \var{msg\_perm.uid} e \var{msg\_perm.gid} occorre essere il proprietario o il creatore della coda, oppure l'amministratore; lo - stesso vale per \var{msg\_qbytes}, con la restrizione che solo - l'amministratore può incrementarne il valore a limiti superiori a - \macro{MSGMNB}. + stesso vale per \var{msg\_qbytes}, ma l'amministratore ha la facoltà di + incrementarne il valore a limiti superiori a \macro{MSGMNB}. \end{basedescript} @@ -1402,29 +1413,39 @@ La funzione inserisce il messaggio sulla coda specificata da \param{msqid}; il messaggio ha lunghezza specificata da \param{msgsz} ed è passato attraverso l'argomento \param{msgp}. Quest'ultimo deve venire passato sempre in una forma che corrisponda alla struttura \var{msgbuf} riportata in -\figref{fig:ipc_msbug}. La struttura è solo un modello, la sola cosa che -conta è abbia come primo membro un campo \var{mtype}, come nell'esempio; esso -infatti serve ad identificare il tipo di messaggio e deve essere sempre -specificato come intero positivo. Il campo \var{mtext} invece può essere di -qualsiasi tipo e dimensione, e deve contenere il testo del messaggio. - -In generale pertanto occorrerà ridefinire una struttura analoga a quella di -\figref{fig:ipc_msbug}, adattando alle proprie esigenze il campo \var{mtype}, -e avendo cura di mantenere come primo campo un valore di tipo \ctyp{long}. Il -resto della struttura andrà a costituire il corpo del messaggio, la cui -dimensione deve essere specificata sempre attraverso \param{msgsz}. Si tenga -presente che la lunghezza che deve essere indicata in questo argomento è solo -quella del messaggio, non di tutta la struttura, se cioè \var{message} è la -struttura che si passa alla funzione, \param{msgsz} dovrà essere uguale a -\code{sizeof(message)-sizeof(long)}. +\figref{fig:ipc_msbug}. La dimensione massima per il testo di un messaggio +non può comunque superare il limite \macro{MSGMAX}. + +La struttura di \figref{fig:ipc_msbug} comunque è solo un modello, tanto che +la definizione contenuta in \file{sys/msg.h} usa esplicitamente per il secondo +campo il valore \code{mtext[1]}, che non è di nessuna utilità ai fini pratici. +La sola cosa che conta è che abbia come primo membro un campo \var{mtype}, +come nell'esempio; esso infatti serve ad identificare il tipo di messaggio e +deve essere sempre specificato come intero positivo. Il campo \var{mtext} +invece può essere di qualsiasi tipo e dimensione, e deve contenere il testo +del messaggio. + +In generale pertanto per inviare un messaggio con \func{msgsnd} si usa +ridefinire una struttura simile a quella di \figref{fig:ipc_msbug}, adattando +alle proprie esigenze il campo \var{mtype}, (o ridefinendo come si vuole il +corpo del messaggio, anche con più campi o con strutture più complesse) avendo +però la cura di mantenere nel primo campo un valore di tipo \ctyp{long} che ne +indica il tipo. + +Si tenga presente che la lunghezza che deve essere indicata in questo +argomento è solo quella del messaggio, non quella di tutta la struttura, se +cioè \var{message} è una propria struttura che si passa alla funzione, +\param{msgsz} dovrà essere uguale a \code{sizeof(message)-sizeof(long)}, (se +consideriamo il caso dell'esempio in \figref{fig:ipc_msbug}, \param{msgsz} +dovrà essere pari a \macro{LENGHT}). \begin{figure}[!htb] \footnotesize \centering \begin{minipage}[c]{15cm} \begin{lstlisting}[labelstep=0]{} struct msgbuf { - long mtype; /* message type, must be > 0 */ - char mtext[1]; /* message data */ + long mtype; /* message type, must be > 0 */ + char mtext[LENGTH]; /* message data */ }; \end{lstlisting} \end{minipage} @@ -1463,12 +1484,12 @@ interrotta da un segnale (nel qual caso si ha un errore di \macro{EINTR}). Una volta completato con successo l'invio del messaggio sulla coda, la funzione aggiorna i dati mantenuti in \var{msqid\_ds}, in particolare vengono modificati: -\begin{itemize*} -\item Il valore di \var{msg\_lspid}, che viene importato al \acr{pid} del +\begin{itemize} +\item Il valore di \var{msg\_lspid}, che viene impostato al \acr{pid} del processo chiamante. \item Il valore di \var{msg\_qnum}, che viene incrementato di uno. \item Il valore \var{msg\_stime}, che viene impostato al tempo corrente. -\end{itemize*} +\end{itemize} La funzione che permette di estrarre da una coda un messaggio (che sarà @@ -1500,27 +1521,75 @@ rimosso dalla stessa) } \end{functions} -La funzione è analoga alla precedente \func{msgsnd} ed gli argomenti sono -analoghi, con l'eccezione di \param{type}, questo permette di restringere la -ricerca ad alcuni messaggi; in particolare: +La funzione legge un messaggio dalla coda specificata scrivendolo nel buffer +indicato da \param{msgp}, che avrà un formato analogo a quello di +\figref{fig:ipc_msbug}. L'argomento \param{msgsz} indica la lunghezza massima +del testo del messaggio (equivalente al valore del parametro \macro{LENGHT} +nell'esempio di \figref{fig:ipc_msbug}). + +Se il testo del messaggio ha lunghezza inferiore a \param{msgsz} esso viene +rimosso dalla coda; in caso contrario, se \param{msgflg} è impostato a +\macro{MSG\_NOERROR}, il messaggio viene troncato e la parte in eccesso viene +perduta, altrimenti il messaggio non viene estratto e la funzione ritorna con +un errore di \macro{E2BIG}. + +L'argomento \param{msgtyp} permette di restringere la ricerca ad un +sottoinsieme dei messaggi presenti sulla coda; la ricerca infatti è fatta con +una scansione della struttura mostrata in \figref{fig:ipc_mq_schema}, +restituendo il primo messaggio incontrato che corrisponde ai criteri +specificati (che quindi, visto che i messaggi vengono sempre inseriti dalla +coda, è quello meno recente); in particolare: \begin{itemize} -\item se \param{type} è 0 viene estratto il messaggio in cima alla coda (cioè - quello fra i presenti che è stato inserito inserito per primo). -\item se \param{type} è positivo viene estratto il primo messaggio il cui tipo - (il valore del campo \var{mtype}) corrisponde a quanto specificato. -\item se \param{type} è negativo viene estratto il primo messaggio il valore - di tipo più basso inferiore al valore assoluto di quanto specificato. +\item se \param{msgtyp} è 0 viene estratto il messaggio in cima alla coda, cioè + quello fra i presenti che è stato inserito inserito per primo. +\item se \param{msgtyp} è positivo viene estratto il primo messaggio il cui + tipo (il valore del campo \var{mtype}) corrisponde al valore di + \param{msgtyp}. +\item se \param{msgtyp} è negativo viene estratto il primo fra i messaggi con + il tipo di valore più basso, fra tutti quelli con un tipo inferiore al + valore assoluto di \param{msgtyp}. \end{itemize} +Il valore di \param{msgflg} permette di controllare il comportamento della +funzione, esso può essere nullo o una maschera binaria composta da uno o più +valori. Oltre al precedente \macro{MSG\_NOERROR}, sono possibili altri due +valori: \macro{MSG\_EXCEPT}, che permette, quando \param{msgtyp} è positivo, +di leggere il primo messaggio nella coda con tipo diverso da \param{msgtyp}, e +\macro{IPC\_NOWAIT} che causa il ritorno immediato della funzione quando non +ci sono messaggi sulla coda. + +Il comportamento usuale della funzione infatti, se non ci sono messaggi +disponibili per la lettura, è di bloccare il processo in stato di +\textit{sleep}. Nel caso però si sia specificato \macro{IPC\_NOWAIT} la +funzione ritorna immediatamente con un errore \macro{ENOMSG}. Altrimenti la +funzione ritorna normalmente non appena viene inserito un messaggio del tipo +desiderato, oppure ritorna con errore qualora la coda sia rimossa (con +\var{errno} settata a \macro{EIDRM}) o se il processo viene interrotto da un +segnale (con \var{errno} settata a \macro{EINTR}). + +Una volta completata con successo l'estrazione del messaggio dalla coda, la +funzione aggiorna i dati mantenuti in \var{msqid\_ds}, in particolare vengono +modificati: +\begin{itemize} +\item Il valore di \var{msg\_lrpid}, che viene impostato al \acr{pid} del + processo chiamante. +\item Il valore di \var{msg\_qnum}, che viene decrementato di uno. +\item Il valore \var{msg\_rtime}, che viene impostato al tempo corrente. +\end{itemize} +Come esempio dell'uso delle code di messaggi possiamo riscrivere il nostro +server di \textit{fortunes} usando queste al posto delle fifo. In questo caso +useremo una coda di messaggi, usando il \acr{pid} del client come valore per +il tipo di messaggio, per restituire indietro le frasi ai client. \subsection{Semafori} \label{sec:ipc_sysv_sem} Il secondo oggetto introdotto dal \textit{System V IPC} è quello dei semafori. Un semaforo è uno speciale contatore che permette di controllare l'accesso a -risorse condivise. La funzione che permette di ottenere un insieme di semafori -è \func{semget} ed il suo prototipo è: +risorse condivise. La funzione che permette di creare o ottenere +l'identificatore di un insieme di semafori è \func{semget}, ed il suo prototipo +è: \begin{functions} \headdecl{sys/types.h} \headdecl{sys/ipc.h} @@ -1528,7 +1597,7 @@ risorse condivise. La funzione che permette di ottenere un insieme di semafori \funcdecl{int semget(key\_t key, int nsems, int flag)} - Restituisce l'identificatore di un semaforo. + Restituisce l'identificatore di un insieme di semafori. \bodydesc{La funzione restituisce l'identificatore (un intero positivo) o -1 in caso di errore, nel qual caso \var{errno} viene settato agli stessi @@ -1542,6 +1611,59 @@ specificare quanti semafori deve contenere l'insieme qualora se ne richieda la creazione, e deve essere nullo quando si effettua una richiesta dell'identificatore di un insieme già esistente. +A ciascun insieme di semafori è associata una struttura \var{semid\_ds}, +riportata in \figref{fig:ipc_semid_sd}, come nel caso delle code di messaggi +quando si crea un nuovo insieme di semafori con \func{semget} questa struttura +viene inizializzata, in particolare il campo \var{sem\_perm} viene +inizializzato come illustrato in \secref{sec:ipc_sysv_access_control}, per +quanto riguarda gli altri campi invece: +\begin{itemize*} +\item il campo \var{sem\_nsems}, che esprime il numero di semafori + nell'insieme, viene inizializzato al valore di \param{nsems}. +\item il campo \var{sem\_ctime}, che esprime il tempo di creazione + dell'insieme, viene inizializzato al tempo corrente +\item il campo \var{sem\_otime}, che esprime il tempo dell'ultima operazione + effettuata, viene inizializzato a zero. +\end{itemize*} + +\begin{figure}[!htb] + \footnotesize \centering + \begin{minipage}[c]{15cm} + \begin{lstlisting}[labelstep=0]{} +struct semid_ds +{ + struct ipc_perm sem_perm; /* operation permission struct */ + time_t sem_otime; /* last semop() time */ + time_t sem_ctime; /* last time changed by semctl() */ + unsigned long int sem_nsems; /* number of semaphores in set */ +}; + \end{lstlisting} + \end{minipage} + \normalsize + \caption{La struttura \var{semid\_ds}, associata a ciascun insieme di + semafori.} + \label{fig:ipc_semid_sd} +\end{figure} + +\begin{table}[htb] + \footnotesize + \centering + \begin{tabular}[c]{|c|r|l|l|} + \hline + \textbf{Costante} & \textbf{Valore} & \textbf{Significato} \\ + \hline + \hline + \macro{SEMMNI}& 16& Numero massimo di insiemi di semafori. \\ + \macro{SEMMAX}& 8192& .\\ + \macro{SEMMNB}&16384& .\\ + \hline + \end{tabular} + \caption{Valori delle costanti associate ai limiti degli insiemi di + semafori.} + \label{tab:ipc_sem_limits} +\end{table} + + \subsection{Memoria condivisa}