X-Git-Url: https://gapil.gnulinux.it/gitweb/?p=gapil.git;a=blobdiff_plain;f=ipc.tex;h=654ec7d6083c0e0bd2467031a59d50275aa245a9;hp=080d33bcc4e37f35a6bc79d01d612b3911120e7d;hb=a609782c8411e35c6d0a41f6b036674ab3034612;hpb=74b559a3958675adf01c9a906cdd485eaf399290 diff --git a/ipc.tex b/ipc.tex index 080d33b..654ec7d 100644 --- a/ipc.tex +++ b/ipc.tex @@ -1,6 +1,6 @@ %% ipc.tex %% -%% Copyright (C) 2000-2006 Simone Piccardi. Permission is granted to +%% Copyright (C) 2000-2007 Simone Piccardi. Permission is granted to %% copy, distribute and/or modify this document under the terms of the GNU Free %% Documentation License, Version 1.1 or any later version published by the %% Free Software Foundation; with the Invariant Sections being "Un preambolo", @@ -8,6 +8,7 @@ %% license is included in the section entitled "GNU Free Documentation %% License". %% + \chapter{La comunicazione fra processi} \label{cha:IPC} @@ -169,7 +170,7 @@ direzione del flusso dei dati Si potrebbe obiettare che sarebbe molto più semplice salvare il risultato intermedio su un file temporaneo. Questo però non tiene conto del fatto che un \textit{CGI} deve poter gestire più richieste in concorrenza, e si avrebbe una -evidente \textit{race condition}\itindex{race~condition} in caso di accesso +evidente \itindex{race~condition} \textit{race condition} in caso di accesso simultaneo a detto file.\footnote{il problema potrebbe essere superato determinando in anticipo un nome appropriato per il file temporaneo, che verrebbe utilizzato dai vari sotto-processi, e cancellato alla fine della @@ -417,13 +418,13 @@ o nella relazione padre/figlio; per superare questo problema lo standard POSIX.1 ha definito dei nuovi oggetti, le \textit{fifo}, che hanno le stesse caratteristiche delle pipe, ma che invece di essere strutture interne del kernel, visibili solo attraverso un file descriptor, sono accessibili -attraverso un inode\index{inode} che risiede sul filesystem, così che i +attraverso un \index{inode} inode che risiede sul filesystem, così che i processi le possono usare senza dovere per forza essere in una relazione di \textsl{parentela}. Utilizzando una \textit{fifo} tutti i dati passeranno, come per le pipe, attraverso un apposito buffer nel kernel, senza transitare dal filesystem; -l'inode\index{inode} allocato sul filesystem serve infatti solo a fornire un +\index{inode} l'inode allocato sul filesystem serve infatti solo a fornire un punto di riferimento per i processi, che permetta loro di accedere alla stessa fifo; il comportamento delle funzioni di lettura e scrittura è identico a quello illustrato per le pipe in sez.~\ref{sec:ipc_pipes}. @@ -453,8 +454,8 @@ 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 situazioni di stallo.\footnote{se si cerca di leggere da una fifo che non contiene dati si - avrà un deadlock\itindex{deadlock} immediato, dato che il processo si blocca - e non potrà quindi mai eseguire le funzioni di scrittura.} + avrà un \itindex{deadlock} 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 @@ -648,7 +649,7 @@ state raccolte nella libreria \file{libgapil.so}, per poter usare quest'ultima occorrerà definire la speciale variabile di ambiente \code{LD\_LIBRARY\_PATH} in modo che il linker dinamico possa accedervi. -In generale questa variabile indica il \itindex{pathname}\textit{pathname} +In generale questa variabile indica il \itindex{pathname} \textit{pathname} della directory contenente la libreria. Nell'ipotesi (che daremo sempre per verificata) che si facciano le prove direttamente nella directory dei sorgenti (dove di norma vengono creati sia i programmi che la libreria), il comando da @@ -878,7 +879,7 @@ nome di un file ed un numero di versione; il suo prototipo \end{functions} La funzione determina un valore della chiave sulla base di \param{pathname}, -che deve specificare il \itindex{pathname}\textit{pathname} di un file +che deve specificare il \itindex{pathname} \textit{pathname} di un file effettivamente esistente e di un numero di progetto \param{proj\_id)}, che di norma viene specificato come carattere, dato che ne vengono utilizzati solo gli 8 bit meno significativi.\footnote{nelle libc4 e libc5, come avviene in @@ -888,7 +889,7 @@ gli 8 bit meno significativi.\footnote{nelle libc4 e libc5, come avviene in Il problema è che anche così non c'è la sicurezza che il valore della chiave sia univoco, infatti esso è costruito combinando il byte di \param{proj\_id)} -con i 16 bit meno significativi dell'inode\index{inode} del file +con i 16 bit meno significativi \index{inode} dell'inode del file \param{pathname} (che vengono ottenuti attraverso \func{stat}, da cui derivano i possibili errori), e gli 8 bit meno significativi del numero del dispositivo su cui è il file. Diventa perciò relativamente facile ottenere delle @@ -977,7 +978,7 @@ a differenza di quanto avviene per i permessi dei file, fallire in uno dei passi elencati non comporta il fallimento dell'accesso. Un'ulteriore differenza rispetto a quanto avviene per i file è che per gli oggetti di IPC il valore di \var{umask} (si ricordi quanto esposto in -sez.~\ref{sec:file_umask}) non ha alcun significato. +sez.~\ref{sec:file_perm_management}) non ha alcun significato. \subsection{Gli identificatori ed il loro utilizzo} @@ -1184,23 +1185,23 @@ file \file{msgmax}, \file{msgmnb} e \file{msgmni} di \file{/proc/sys/kernel/}. \end{figure} -Una coda di messaggi è costituita da una \itindex{linked~list}\textit{linked - list};\footnote{una \textit{linked list} è una tipica struttura di dati, - organizzati in una lista in cui ciascun elemento contiene un puntatore al - successivo. In questo modo la struttura è veloce nell'estrazione ed - immissione dei dati dalle estremità dalla lista (basta aggiungere un - elemento in testa o in coda ed aggiornare un puntatore), e relativamente - veloce da attraversare in ordine sequenziale (seguendo i puntatori), è - invece relativamente lenta nell'accesso casuale e nella ricerca.} i nuovi -messaggi vengono inseriti in coda alla lista e vengono letti dalla cima, in -fig.~\ref{fig:ipc_mq_schema} si è riportato lo schema con cui queste strutture -vengono mantenute dal kernel.\footnote{lo schema illustrato in - fig.~\ref{fig:ipc_mq_schema} è in realtà una semplificazione di quello usato - effettivamente fino ai kernel della serie 2.2.x, nei kernel della serie - 2.4.x la gestione delle code di messaggi è stata modificata ed è effettuata - in maniera diversa; abbiamo mantenuto lo schema precedente in quanto - illustra comunque in maniera più che adeguata i principi di funzionamento - delle code di messaggi.} +Una coda di messaggi è costituita da una \itindex{linked~list} \textit{linked + list};\footnote{una \itindex{linked~list} \textit{linked list} è una tipica + struttura di dati, organizzati in una lista in cui ciascun elemento contiene + un puntatore al successivo. In questo modo la struttura è veloce + nell'estrazione ed immissione dei dati dalle estremità dalla lista (basta + aggiungere un elemento in testa o in coda ed aggiornare un puntatore), e + relativamente veloce da attraversare in ordine sequenziale (seguendo i + puntatori), è invece relativamente lenta nell'accesso casuale e nella + ricerca.} i nuovi messaggi vengono inseriti in coda alla lista e vengono +letti dalla cima, in fig.~\ref{fig:ipc_mq_schema} si è riportato lo schema con +cui queste strutture vengono mantenute dal kernel.\footnote{lo schema + illustrato in fig.~\ref{fig:ipc_mq_schema} è in realtà una semplificazione + di quello usato effettivamente fino ai kernel della serie 2.2.x, nei kernel + della serie 2.4.x la gestione delle code di messaggi è stata modificata ed è + effettuata in maniera diversa; abbiamo mantenuto lo schema precedente in + quanto illustra comunque in maniera più che adeguata i principi di + funzionamento delle code di messaggi.} \begin{figure}[!htb] \footnotesize \centering @@ -1516,7 +1517,7 @@ possono essere utilizzate, e non si ha a disposizione niente di analogo alle funzioni \func{select} e \func{poll}. Questo rende molto scomodo usare più di una di queste strutture alla volta; ad esempio non si può scrivere un server che aspetti un messaggio su più di una coda senza fare ricorso ad una tecnica -di \textit{polling}\itindex{polling} che esegua un ciclo di attesa su +di \itindex{polling} \textit{polling} che esegua un ciclo di attesa su ciascuna di esse. Come esempio dell'uso delle code di messaggi possiamo riscrivere il nostro @@ -1679,7 +1680,7 @@ viene interrotto dopo l'invio del messaggio di richiesta e prima della lettura della risposta, quest'ultima resta nella coda (così come per le fifo si aveva il problema delle fifo che restavano nel filesystem). In questo caso però il problemi sono maggiori, sia perché è molto più facile esaurire la memoria -dedicata ad una coda di messaggi che gli inode\index{inode} di un filesystem, +dedicata ad una coda di messaggi che gli \index{inode} inode di un filesystem, sia perché, con il riutilizzo dei \acr{pid} da parte dei processi, un client eseguito in un momento successivo potrebbe ricevere un messaggio non indirizzato a lui. @@ -1692,8 +1693,8 @@ indirizzato a lui. I semafori non sono meccanismi di intercomunicazione diretta come quelli (pipe, fifo e code di messaggi) visti finora, e non consentono di scambiare dati fra processi, ma servono piuttosto come meccanismi di sincronizzazione o -di protezione per le \textsl{sezioni critiche} \index{sezione~critica} del -codice (si ricordi quanto detto in sez.~\ref{sec:proc_race_cond}). +di protezione per le \index{sezione~critica} \textsl{sezioni critiche} del +codice (si ricordi quanto detto in sez.~\ref{sec:proc_race_cond}). Un semaforo è uno speciale contatore, mantenuto nel kernel, che permette, a seconda del suo valore, di consentire o meno la prosecuzione dell'esecuzione @@ -2196,7 +2197,7 @@ coda di attesa associata a ciascun insieme di semafori\footnote{che viene Nella struttura viene memorizzato il riferimento alle operazioni richieste (nel campo \var{sops}, che è un puntatore ad una struttura \struct{sembuf}) e al processo corrente (nel campo \var{sleeper}) poi quest'ultimo viene messo -stato di attesa e viene invocato lo scheduler\itindex{scheduler} per passare +stato di attesa e viene invocato lo \itindex{scheduler} scheduler per passare all'esecuzione di un altro processo. Se invece tutte le operazioni possono avere successo queste vengono eseguite @@ -2510,14 +2511,14 @@ corrispondente comportamento della funzione, sono i seguenti: memoria virtuale; si ricordi quanto trattato in sez.~\ref{sec:proc_mem_lock}.} sul segmento di memoria condivisa. Solo l'amministratore può utilizzare questo comando. -\item[\const{SHM\_UNLOCK}] Disabilita il \textit{memory locking} - \itindex{memory~locking} sul segmento di memoria condivisa. Solo +\item[\const{SHM\_UNLOCK}] Disabilita il \itindex{memory~locking} + \textit{memory locking} sul segmento di memoria condivisa. Solo l'amministratore può utilizzare questo comando. \end{basedescript} i primi tre comandi sono gli stessi già visti anche per le code di messaggi e gli insiemi di semafori, gli ultimi due sono delle estensioni specifiche previste da Linux, che permettono di abilitare e disabilitare il meccanismo -della memoria virtuale \index{memoria~virtuale} per il segmento. +della \index{memoria~virtuale} memoria virtuale per il segmento. L'argomento \param{buf} viene utilizzato solo con i comandi \const{IPC\_STAT} e \const{IPC\_SET} nel qual caso esso dovrà puntare ad una struttura @@ -2556,7 +2557,7 @@ direttamente, la situazione dopo l'esecuzione di \func{shmat} fig.~\ref{fig:ipc_shmem_layout} (per la comprensione del resto dello schema si ricordi quanto illustrato al proposito in sez.~\ref{sec:proc_mem_layout}). In particolare l'indirizzo finale del segmento dati (quello impostato da -\func{brk}, vedi sez.~\ref{sec:proc_mem_sbrk_alloca}) non viene influenzato. +\func{brk}, vedi sez.~\ref{sec:proc_mem_alloc}) non viene influenzato. Si tenga presente infine che la funzione ha successo anche se il segmento è stato marcato per la cancellazione. @@ -3020,6 +3021,7 @@ diffuso. \label{sec:ipc_file_lock} \index{file!di lock|(} + Come illustrato in sez.~\ref{sec:ipc_sysv_sem} i semafori del \textit{SysV IPC} presentano una interfaccia inutilmente complessa e con alcuni difetti strutturali, per questo quando si ha una semplice esigenza di sincronizzazione @@ -3076,35 +3078,36 @@ acquisizione sono atomici; la soluzione funziona anche su NFS, ma ha un altro difetto è che è quello di poterla usare solo se si opera all'interno di uno stesso filesystem. -Un generale comunque l'uso di un \textsl{file di lock} presenta parecchi -problemi, che non lo rendono una alternativa praticabile per la +In generale comunque l'uso di un \textsl{file di lock} presenta parecchi +problemi che non lo rendono una alternativa praticabile per la sincronizzazione: anzitutto in caso di terminazione imprevista del processo, si lascia allocata la risorsa (il \textsl{file di lock}) e questa deve essere sempre cancellata esplicitamente. Inoltre il controllo della disponibilità -può essere eseguito solo con una tecnica di \textit{polling}\itindex{polling}, -ed è quindi molto inefficiente. +può essere eseguito solo con una tecnica di \itindex{polling} +\textit{polling}, ed è quindi molto inefficiente. La tecnica dei file di lock ha comunque una sua utilità, e può essere usata con successo quando l'esigenza è solo quella di segnalare l'occupazione di una risorsa, senza necessità di attendere che questa si liberi; ad esempio la si usa spesso per evitare interferenze sull'uso delle porte seriali da parte di più programmi: qualora si trovi un file di lock il programma che cerca di -accedere alla seriale si limita a segnalare che la risorsa non è -disponibile.\index{file!di lock|)} +accedere alla seriale si limita a segnalare che la risorsa non è disponibile. + +\index{file!di lock|)} \subsection{La sincronizzazione con il \textit{file locking}} \label{sec:ipc_lock_file} -Dato che i file di lock\index{file!di lock} presentano gli inconvenienti +Dato che i \index{file!di lock} file di lock presentano gli inconvenienti illustrati in precedenza, la tecnica alternativa di sincronizzazione più -comune è quella di fare ricorso al \textit{file locking}\index{file!locking} +comune è quella di fare ricorso al \index{file!locking} \textit{file locking} (trattato in sez.~\ref{sec:file_locking}) usando \func{fcntl} su un file creato per l'occasione per ottenere un write lock. In questo modo potremo usare il lock come un \textit{mutex}: per bloccare la risorsa basterà acquisire il lock, per sbloccarla basterà rilasciare il lock. Una richiesta fatta con un write lock metterà automaticamente il processo in stato di -attesa, senza necessità di ricorrere al \textit{polling}\itindex{polling} per +attesa, senza necessità di ricorrere al \itindex{polling} \textit{polling} per determinare la disponibilità della risorsa, e al rilascio della stessa da parte del processo che la occupava si otterrà il nuovo lock atomicamente. @@ -3274,67 +3277,65 @@ richiesto \end{itemize} Data la assoluta genericità delle specifiche, il comportamento delle funzioni -è pertanto subordinato in maniera quasi completa alla relativa +è subordinato in maniera quasi completa alla relativa implementazione.\footnote{tanto che Stevens in \cite{UNP2} cita questo caso come un esempio della maniera standard usata dallo standard POSIX per consentire implementazioni non standardizzabili.} Nel caso di Linux, sia per -quanto riguarda la memoria condivisa, che per quanto riguarda le code di -messaggi, tutto viene creato usando come radici delle opportune directory -(rispettivamente \file{/dev/shm} e \file{/dev/mqueue}, per i dettagli si -faccia riferimento a sez.~\ref{sec:ipc_posix_shm} e -sez.~\ref{sec:ipc_posix_mq}) ed i nomi specificati nelle relative funzioni -sono considerati come un \itindsub{pathname}{assoluto}\textit{pathname} -assoluto (comprendente eventuali sottodirectory) rispetto a queste radici. +quanto riguarda la memoria condivisa ed i semafori, che per quanto riguarda le +code di messaggi, tutto viene creato usando come radici delle opportune +directory (rispettivamente \file{/dev/shm} e \file{/dev/mqueue}, per i +dettagli si faccia riferimento a sez.~\ref{sec:ipc_posix_shm}, +sez.~\ref{sec:ipc_posix_sem} e sez.~\ref{sec:ipc_posix_mq}) ed i nomi +specificati nelle relative funzioni sono considerati come un +\itindsub{pathname}{assoluto}\textit{pathname} assoluto (comprendente +eventuali sottodirectory) rispetto a queste radici. Il vantaggio degli oggetti di IPC POSIX è comunque che essi vengono inseriti nell'albero dei file, e possono essere maneggiati con le usuali funzioni e -comandi di accesso ai file,\footnote{questo è ancora più vero nel caso di - Linux, che usa una implementazione che lo consente, non è detto che - altrettanto valga per altri kernel. In particolare sia la memoria condivisa - che per le code di messaggi, come si può facilmente evincere con uno - \cmd{strace}, le system call utilizzate sono le stesse, in quanto esse sono - realizzate con dei file in speciali filesystem.} che funzionano come su dei -file normali. +comandi di accesso ai file,\footnote{questo è vero nel caso di Linux, che usa + una implementazione che lo consente, non è detto che altrettanto valga per + altri kernel; in particolare sia la memoria condivisa che per le code di + messaggi, come si può facilmente evincere con uno \cmd{strace}, le system + call utilizzate sono le stesse, in quanto detti oggetti sono realizzati con + dei file in speciali filesystem.} che funzionano come su dei file normali. In particolare i permessi associati agli oggetti di IPC POSIX sono identici ai permessi dei file, e il controllo di accesso segue esattamente la stessa semantica (quella illustrata in sez.~\ref{sec:file_access_control}), invece di quella particolare (si ricordi quanto visto in -sez.~\ref{sec:ipc_sysv_access_control}) usata per gli oggetti del SysV IPC. Per -quanto riguarda l'attribuzione dell'utente e del gruppo proprietari +sez.~\ref{sec:ipc_sysv_access_control}) usata per gli oggetti del SysV IPC. +Per quanto riguarda l'attribuzione dell'utente e del gruppo proprietari dell'oggetto alla creazione di quest'ultimo essa viene effettuata secondo la -semantica SysV (essi corrispondono cioè a userid e groupid effettivi del -processo che esegue la creazione). +semantica SysV; essi corrispondono cioè a userid e groupid effettivi del +processo che esegue la creazione. \subsection{Code di messaggi} \label{sec:ipc_posix_mq} -Le code di messaggi non sono ancora supportate nel kernel ufficiale, esiste -però una implementazione sperimentale di Michal Wronski e Krzysztof -Benedyczak,\footnote{i patch al kernel e la relativa libreria possono essere -trovati su \href{http://www.mat.uni.torun.pl/~wrona/posix_ipc} -{\textsf{http://www.mat.uni.torun.pl/\tild{}wrona/posix\_ipc}}, questi sono -stati inseriti nel kernel ufficiale a partire dalla versione 2.6.6-rc1.}. In +Le code di messaggi POSIX sono supportate da Linux a partire dalla versione +2.6.6-rc1 del kerne;, \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 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 mutex e memoria condivisa con tutta la flessibilità che -occorre. - -Per poter utilizzare le code di messaggi, oltre ad utilizzare un kernel cui -siano stati opportunamente applicati i relativi patch, occorre utilizzare la -libreria \file{mqueue}\footnote{i programmi che usano le code di messaggi cioè +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 +mutex (o semafori) e memoria condivisa con tutta la flessibilità che occorre. + +Per poter utilizzare le code di messaggi, oltre ad utilizzare un kernel +superiore al 2.6.6 (o precedente, purché cui siano stati opportunamente +applicati i relativi patch) occorre utilizzare la libreria +\file{libmqueue}\footnote{i programmi che usano le code di messaggi cioè devono essere compilati aggiungendo l'opzione \code{-lmqueue} al comando \cmd{gcc}, dato che le funzioni non fanno parte della libreria standard, in corrispondenza all'inclusione del supporto nel kernel ufficiale, anche le - relative funzioni sono state inserite nelle \acr{glibc} a partire dalla - versione 2.3.4.} che contiene le funzioni dell'interfaccia -POSIX.\footnote{in realtà l'implementazione è realizzata tramite delle - speciali chiamate ad \func{ioctl} sui file del filesystem speciale su cui - vengono mantenuti questi oggetti di IPC.} - + relative funzioni sono state inserite nelle \acr{glibc}, e presenti a + partire dalla versione 2.3.4 delle medesime.} che contiene le funzioni +dell'interfaccia POSIX.\footnote{in realtà l'implementazione è realizzata + tramite delle speciali chiamate ad \func{ioctl} sui file del filesystem + speciale su cui vengono mantenuti questi oggetti di IPC.} La libreria inoltre richiede la presenza dell'apposito filesystem di tipo \texttt{mqueue} montato su \file{/dev/mqueue}; questo può essere fatto @@ -3584,11 +3585,16 @@ valore della priorit \const{MQ\_PRIO\_MAX}, che nel caso è pari a 32768. Qualora la coda sia piena, entrambe le funzioni si bloccano, a meno che non -sia stata selezionata in fase di apertura la modalità non bloccante, nel qual -caso entrambe ritornano \errcode{EAGAIN}. La sola differenza fra le due -funzioni è che la seconda, passato il tempo massimo impostato con l'argomento -\param{abs\_timeout}, ritorna comunque con un errore di \errcode{ETIMEDOUT}. - +sia stata selezionata in fase di apertura la modalità non +bloccante,\footnote{o si sia impostato il flag \const{O\_NONBLOCK} sul fie + descriptor della coda.} nel qual caso entrambe ritornano \errcode{EAGAIN}. +La sola differenza fra le due funzioni è che la seconda, passato il tempo +massimo impostato con l'argomento \param{abs\_timeout},\footnote{deve essere + specificato un tempo assoluto tramite una struttura \struct{timespec} (vedi + fig.~\ref{fig:sys_timeval_struct}) indicato in numero di secondi e + nanosecondi a partire dal 1 gennaio 1970.} ritorna comunque con un errore di +\errcode{ETIMEDOUT}, se invece il tempo è già scaduto al momento della +chiamata e la coda è vuota la funzione ritorna immediatamente. Come per l'inserimento, anche per l'estrazione dei messaggi da una coda sono previste due funzioni, \funcd{mq\_receive} e \funcd{mq\_timedreceive}, i cui @@ -3625,7 +3631,11 @@ prototipi sono: La funzione estrae dalla coda il messaggio a priorità più alta, o il più vecchio fra quelli della stessa priorità. Una volta ricevuto il messaggio viene tolto dalla coda e la sua dimensione viene restituita come valore di -ritorno. +ritorno.\footnote{si tenga presente che 0 è una dimensione valida la + condizione di errore è restituita dal valore -1; Stevens in \cite{UNP2} fa + notare che questo è uno dei casi in cui vale ciò che lo standard + \textsl{non} dice, una dimenzione nulla infatti, pur non essendo citata, non + viene proibita.} Se la dimensione specificata da \param{msg\_len} non è sufficiente a contenere il messaggio, entrambe le funzioni, al contrario di quanto avveniva nelle code @@ -3644,10 +3654,8 @@ Qualora non interessi usare la priorit Si noti che con le code di messaggi POSIX non si ha la possibilità di selezionare quale messaggio estrarre con delle condizioni sulla priorità, a differenza di quanto avveniva con le code di messaggi di SysV che permettono -invece la selezione in base al valore del campo \var{mtype}. Qualora non -interessi usare la priorità dei messaggi si +invece la selezione in base al valore del campo \var{mtype}. -% TODO vericare questa interruzione di paragrafo % TODO inserire i dati di /proc/sys/fs/mqueue Qualora la coda sia vuota entrambe le funzioni si bloccano, a meno che non si @@ -3747,7 +3755,7 @@ all'userid effettivo, \var{si\_code} a \const{SI\_MESGQ}, e \var{si\_errno} a 0. Questo ci dice che, se si effettua la ricezione dei messaggi usando esclusivamente il meccanismo di notifica, è possibile ottenere le informazioni sul processo che ha inserito un messaggio usando un gestore per il segnale in -forma estesa\footnote{di nuovo si faccia riferimento a quanto detto al +forma estesa.\footnote{di nuovo si faccia riferimento a quanto detto al proposito in sez.~\ref{sec:sig_sigaction} e sez.~\ref{sec:sig_real_time}.} @@ -3769,31 +3777,38 @@ mascherati. In realtà a partire dal kernel 2.5.7 è stato introdotto un meccanismo di sincronizzazione completamente nuovo, basato sui cosiddetti \textit{futex}\footnote{la sigla sta per \textit{fast user mode mutex}.}, con -il quale dovrebbe essere possibile implementare una versione nativa dei -semafori; esso è già stato usato con successo per reimplementare in maniera -più efficiente tutte le direttive di sincronizzazione previste per i thread -POSIX. L'interfaccia corrente è stata stabilizzata a partire dal kernel -2.5.40. +il quale è stato possibile implementare una versione nativa dei semafori; esso +è già stato usato con successo per reimplementare in maniera più efficiente +tutte le direttive di sincronizzazione previste per i thread POSIX; e con il +kernel della serie 2.6 e le nuove versioni delle \acr{glibc} che usano quella +che viene chiamata la \textit{New Posix Thread Library} sono state +implementate tutte le funzioni occorrenti. -% TODO vedere se ci sono novità e trattare la cosa. +Anche in questo caso (come per le code di messaggi) è necessario appoggiarsi +alla libreria per le estensioni \textit{real-time} \texttt{librt}, questo +significa che se si vuole utilizzare questa interfaccia, oltre ad utilizzare +gli opportuni file di definizione, occorrerà compilare i programmi con +l'opzione \texttt{-lrt}. + +% TODO trattare l'argomento a partire da man sem_overview. \subsection{Memoria condivisa} \label{sec:ipc_posix_shm} -La memoria condivisa è l'unico degli oggetti di IPC POSIX già presente nel -kernel ufficiale; in realtà il supporto a questo tipo di oggetti è realizzato -attraverso il filesystem \texttt{tmpfs}, uno speciale filesystem che mantiene -tutti i suoi contenuti in memoria,\footnote{il filesystem \texttt{tmpfs} è - diverso da un normale RAM disk, anch'esso disponibile attraverso il - filesystem \texttt{ramfs}, proprio perché realizza una interfaccia - utilizzabile anche per la memoria condivisa; esso infatti non ha dimensione - fissa, ed usa direttamente la cache interna del kernel (che viene usata - anche per la shared memory in stile SysV). In più i suoi contenuti, essendo - trattati direttamente dalla memoria virtuale\index{memoria~virtuale} possono - essere salvati sullo swap automaticamente.} che viene attivato abilitando -l'opzione \texttt{CONFIG\_TMPFS} in fase di compilazione del kernel. +La memoria condivisa è stato il primo degli oggetti di IPC POSIX inserito nel +kernel ufficiale; il supporto a questo tipo di oggetti è realizzato attraverso +il filesystem \texttt{tmpfs}, uno speciale filesystem che mantiene tutti i +suoi contenuti in memoria,\footnote{il filesystem \texttt{tmpfs} è diverso da + un normale RAM disk, anch'esso disponibile attraverso il filesystem + \texttt{ramfs}, proprio perché realizza una interfaccia utilizzabile anche + per la memoria condivisa; esso infatti non ha dimensione fissa, ed usa + direttamente la cache interna del kernel (che viene usata anche per la + shared memory in stile SysV). In più i suoi contenuti, essendo trattati + direttamente dalla memoria virtuale\index{memoria~virtuale} possono essere + salvati sullo swap automaticamente.} che viene attivato abilitando l'opzione +\texttt{CONFIG\_TMPFS} in fase di compilazione del kernel. Per potere utilizzare l'interfaccia POSIX per le code di messaggi le @@ -3956,12 +3971,6 @@ fare (\texttt{\small 44}) in questo caso restituendo al chiamante il valore di ritorno. - -%%% Local Variables: -%%% mode: latex -%%% TeX-master: "gapil" -%%% End: - % LocalWords: like fifo System POSIX RPC Calls Common Object Request Brocker % LocalWords: Architecture descriptor kernel unistd int filedes errno EMFILE % LocalWords: ENFILE EFAULT BUF sez fig fork Stevens siblings EOF read SIGPIPE @@ -3972,7 +3981,7 @@ restituendo al chiamante il valore di ritorno. % LocalWords: PDF EPS lseek ESPIPE PPM Portable PixMap format pnmcrop PNG pnm % LocalWords: pnmmargin png BarCode inode filesystem l'inode mknod mkfifo RDWR % LocalWords: ENXIO deadlock client reinviate fortunes fortunefilename daemon -% LocalWords: FortuneServer FortuneParse FortuneClient pid libgapil LD LIBR