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}\index{\textit{race~condition}} in caso di
-accesso simultaneo a detto file.\footnote{il problema potrebbe essere superato
+evidente \textit{race condition}\itindex{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
loro esecuzione; ma a questo le cose non sarebbero più tanto semplici.}
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\index{\textit{deadlock}} immediato, dato che il processo si
- blocca e non potrà quindi mai eseguire le funzioni di scrittura.}
+ avrà un deadlock\itindex{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
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
-\index{\textit{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 dare sarà \code{export
- LD\_LIBRARY\_PATH=./}; a questo punto potremo lanciare il server, facendogli
-leggere una decina di frasi, con:
+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
+dare sarà \code{export LD\_LIBRARY\_PATH=./}; a questo punto potremo lanciare
+il server, facendogli leggere una decina di frasi, con:
\begin{verbatim}
[piccardi@gont sources]$ ./fortuned -n10
\end{verbatim}
\end{functions}
La funzione determina un valore della chiave sulla base di \param{pathname},
-che deve specificare il \index{\textit{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
\end{figure}
-Una coda di messaggi è costituita da una
-\index{\textit{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 \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
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}\index{\textit{polling}} che esegua un ciclo di attesa su
+di \textit{polling}\itindex{polling} che esegua un ciclo di attesa su
ciascuna di esse.
Come esempio dell'uso delle code di messaggi possiamo riscrivere il nostro
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\index{\textit{scheduler}} per
-passare all'esecuzione di un altro processo.
+stato di attesa e viene invocato lo scheduler\itindex{scheduler} per passare
+all'esecuzione di un altro processo.
Se invece tutte le operazioni possono avere successo queste vengono eseguite
immediatamente, dopo di che il kernel esegue una scansione della coda di
il creatore del segmento, oppure l'amministratore. Compiuta l'operazione
aggiorna anche il valore del campo \var{shm\_ctime}.
\item[\const{SHM\_LOCK}] Abilita il \textit{memory
- locking}\index{\textit{memory~locking}}\footnote{impedisce cioè che la
- memoria usata per il segmento venga salvata su disco dal meccanismo della
- memoria virtuale\index{memoria~virtuale}; si ricordi quanto trattato in
+ locking}\itindex{memory~locking}\footnote{impedisce cioè che la memoria
+ usata per il segmento venga salvata su disco dal meccanismo della memoria
+ virtuale\index{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}\index{\textit{memory~locking}} sul segmento di memoria condivisa.
- Solo l'amministratore può utilizzare questo comando.
+ locking}\itindex{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
sez.~\ref{sec:file_open}) che prevede\footnote{questo è quanto dettato dallo
standard POSIX.1, ciò non toglie che in alcune implementazioni questa
tecnica possa non funzionare; in particolare per Linux, nel caso di NFS, si
- è comunque soggetti alla possibilità di una race
- condition\index{\textit{race~condition}}.} che essa ritorni un errore quando
+ è comunque soggetti alla possibilità di una \textit{race
+ condition}\itindex{race~condition}.} che essa ritorni un errore quando
usata con i flag di \const{O\_CREAT} e \const{O\_EXCL}. In tal modo la
creazione di un \textsl{file di lock} può essere eseguita atomicamente, il
processo che crea il file con successo si può considerare come titolare del
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}\index{\textit{polling}}, ed è quindi molto inefficiente.
+può essere eseguito solo con una tecnica di \textit{polling}\itindex{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
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}\index{\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.
+attesa, senza necessità di ricorrere al \textit{polling}\itindex{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.
Questo approccio presenta il notevole vantaggio che alla terminazione di un
processo tutti i lock acquisiti vengono rilasciati automaticamente (alla
\subsection{Il \textit{memory mapping} anonimo}
\label{sec:ipc_mmap_anonymous}
+\itindbeg{memory~mapping}
Abbiamo già visto che quando i processi sono \textsl{correlati}\footnote{se
cioè hanno almeno un progenitore comune.} l'uso delle pipe può costituire
una valida alternativa alle code di messaggi; nella stessa situazione si può
nel \textit{memory mapping} anonimo.} Vedremo come utilizzare questa tecnica
più avanti, quando realizzeremo una nuova versione del monitor visto in
sez.~\ref{sec:ipc_sysv_shm} che possa restituisca i risultati via rete.
-
+\itindend{memory~mapping}
\section{Il sistema di comunicazione fra processi di POSIX}
La caratteristica fondamentale dell'interfaccia POSIX è l'abbandono dell'uso
degli identificatori e delle chiavi visti nel SysV IPC, per passare ai
-\textit{Posix IPC names}\index{\textit{Posix~IPC~names}}, che sono
-sostanzialmente equivalenti ai nomi dei file. Tutte le funzioni che creano un
-oggetto di IPC Posix prendono come primo argomento una stringa che indica uno
-di questi nomi; lo standard è molto generico riguardo l'implementazione, ed i
-nomi stessi possono avere o meno una corrispondenza sul filesystem; tutto
-quello che è richiesto è che:
+\textit{Posix IPC names}\itindex{Posix~IPC~names}, che sono sostanzialmente
+equivalenti ai nomi dei file. Tutte le funzioni che creano un oggetto di IPC
+Posix prendono come primo argomento una stringa che indica uno di questi nomi;
+lo standard è molto generico riguardo l'implementazione, ed i nomi stessi
+possono avere o meno una corrispondenza sul filesystem; tutto quello che è
+richiesto è che:
\begin{itemize}
\item i nomi devono essere conformi alle regole che caratterizzano i
- \index{\textit{pathname}}\textit{pathname}, in particolare non essere più
- lunghi di \const{PATH\_MAX} byte e terminati da un carattere nullo.
+ \itindex{pathname}\textit{pathname}, in particolare non essere più lunghi di
+ \const{PATH\_MAX} byte e terminati da un carattere nullo.
\item se il nome inizia per una \texttt{/} chiamate differenti allo stesso
nome fanno riferimento allo stesso oggetto, altrimenti l'interpretazione del
nome dipende dall'implementazione.
(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 \index{\textit{pathname}!assoluto}\textit{pathname}
+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