X-Git-Url: https://gapil.gnulinux.it/gitweb/?p=gapil.git;a=blobdiff_plain;f=ipc.tex;h=092d40fdc6bc27f655f8a1b35802a49ac7399613;hp=4ffca7cd03e7eacbfeefbe844d94cddeefca2305;hb=7b43a7843d483c826a6ed13224208c615a23c4d6;hpb=45e080607c5b618a11038a6afc9f79af9931b2da diff --git a/ipc.tex b/ipc.tex index 4ffca7c..092d40f 100644 --- a/ipc.tex +++ b/ipc.tex @@ -122,7 +122,7 @@ fra \const{O\_NONBLOCK} o \const{O\_CLOEXEC} che hanno l'effetto di impostare su entrambi i file descriptor restituiti dalla funzione i relativi flag, già descritti per \func{open} in tab.~\ref{tab:open_operation_flag}, che attivano rispettivamente la modalità di accesso \textsl{non-bloccante} ed il -\textit{close-on-exec} \itindex{close-on-exec}. +\textit{close-on-exec}. Chiaramente creare una \textit{pipe} all'interno di un singolo processo non serve a niente; se però ricordiamo quanto esposto in @@ -228,14 +228,14 @@ direzione del flusso dei dati è data dalle frecce continue. 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} può essere eseguito più volte in contemporanea, e si avrebbe una -evidente \itindex{race~condition} \textit{race condition} in caso di accesso -simultaneo a detto file da istanze diverse. Il problema potrebbe essere -superato utilizzando un sempre diverso per il file temporaneo, che verrebbe -creato all'avvio di ogni istanza, utilizzato dai sottoprocessi, e cancellato -alla fine della sua esecuzione; ma a questo punto le cose non sarebbero più -tanto semplici. L'uso di una \textit{pipe} invece permette di risolvere il -problema in maniera semplice ed elegante, oltre ad essere molto più -efficiente, dato che non si deve scrivere su disco. +evidente \textit{race condition} in caso di accesso simultaneo a detto file da +istanze diverse. Il problema potrebbe essere superato utilizzando un sempre +diverso per il file temporaneo, che verrebbe creato all'avvio di ogni istanza, +utilizzato dai sottoprocessi, e cancellato alla fine della sua esecuzione; ma +a questo punto le cose non sarebbero più tanto semplici. L'uso di una +\textit{pipe} invece permette di risolvere il problema in maniera semplice ed +elegante, oltre ad essere molto più efficiente, dato che non si deve scrivere +su disco. Il programma ci servirà anche come esempio dell'uso delle funzioni di duplicazione dei file descriptor che abbiamo trattato in @@ -369,8 +369,8 @@ La funzione restituisce il puntatore ad uno stream associato alla input}) in caso di \code{w}. A partire dalla versione 2.9 delle \acr{glibc} (questa è una estensione specifica di Linux) all'argomento \param{type} può essere aggiunta la lettera ``\texttt{e}'' per impostare automaticamente il -flag di \textit{close-on-exec} \itindex{close-on-exec} sul file descriptor -sottostante (si ricordi quanto spiegato in sez.~\ref{sec:file_open_close}). +flag di \textit{close-on-exec} sul file descriptor sottostante (si ricordi +quanto spiegato in sez.~\ref{sec:file_open_close}). Lo \textit{stream} restituito da \func{popen} è identico a tutti gli effetti ai \textit{file stream} visti in sez.~\ref{sec:files_std_interface}, anche se @@ -514,10 +514,10 @@ a quello illustrato per le \textit{pipe} in sez.~\ref{sec:ipc_pipes}. Abbiamo già trattato in sez.~\ref{sec:file_mknod} le funzioni \func{mknod} e \func{mkfifo} che permettono di creare una \textit{fifo}. Per utilizzarne una -un processo non avrà che da aprire il relativo \index{file!speciali} file -speciale o in lettura o scrittura; nel primo caso il processo sarà collegato -al capo di uscita della \textit{fifo}, e dovrà leggere, nel secondo al capo di -ingresso, e dovrà scrivere. +un processo non avrà che da aprire il relativo file speciale o in lettura o +scrittura; nel primo caso il processo sarà collegato al capo di uscita della +\textit{fifo}, e dovrà leggere, nel secondo al capo di ingresso, e dovrà +scrivere. Il kernel alloca un singolo buffer per ciascuna \textit{fifo} che sia stata aperta, e questa potrà essere acceduta contemporaneamente da più processi, sia @@ -821,21 +821,21 @@ presenta il problema della unidirezionalità del flusso dei dati, è quello dei cosiddetti \textsl{socket locali} (o \textit{Unix domain socket}). Tratteremo in generale i socket in cap.~\ref{cha:socket_intro}, nell'ambito dell'interfaccia che essi forniscono per la programmazione di rete, e vedremo -anche (in~sez.~\ref{sec:sock_sa_local}) come si possono utilizzare i -\index{file!speciali} file speciali di tipo socket, analoghi a quelli -associati alle \textit{fifo} (si rammenti sez.~\ref{sec:file_file_types}) cui -si accede però attraverso quella medesima interfaccia; vale però la pena -esaminare qui una modalità di uso dei socket locali che li rende -sostanzialmente identici ad una \textit{pipe} bidirezionale. +anche (in~sez.~\ref{sec:sock_sa_local}) come si possono utilizzare i file +speciali di tipo socket, analoghi a quelli associati alle \textit{fifo} (si +rammenti sez.~\ref{sec:file_file_types}) cui si accede però attraverso quella +medesima interfaccia; vale però la pena esaminare qui una modalità di uso dei +socket locali che li rende sostanzialmente identici ad una \textit{pipe} +bidirezionale. La funzione di sistema \funcd{socketpair}, introdotta da BSD ma supportata in genere da qualunque sistema che fornisca l'interfaccia dei socket ed inclusa in POSIX.1-2001, consente infatti di creare una coppia di file descriptor connessi fra loro (tramite un socket, appunto) senza dover ricorrere ad un -\index{file!speciali} file speciale sul filesystem. I descrittori sono del -tutto analoghi a quelli che si avrebbero con una chiamata a \func{pipe}, con -la sola differenza è che in questo caso il flusso dei dati può essere -effettuato in entrambe le direzioni. Il prototipo della funzione è: +file speciale sul filesystem. I descrittori sono del tutto analoghi a quelli +che si avrebbero con una chiamata a \func{pipe}, con la sola differenza è che +in questo caso il flusso dei dati può essere effettuato in entrambe le +direzioni. Il prototipo della funzione è: \begin{funcproto}{ \fhead{sys/types.h} @@ -1075,8 +1075,7 @@ direttamente (in lettura o scrittura) all'oggetto. In tal caso lo schema dei controlli è simile a quello dei file, ed avviene secondo questa sequenza: \begin{itemize*} \item se il processo ha i privilegi di amministratore (più precisamente la - capacità \itindex{capability} \const{CAP\_IPC\_OWNER}) l'accesso è sempre - consentito. + capacità \const{CAP\_IPC\_OWNER}) l'accesso è sempre consentito. \item se l'\ids{UID} effettivo del processo corrisponde o al valore del campo \var{cuid} o a quello del campo \var{uid} ed il permesso per il proprietario in \var{mode} è appropriato\footnote{per appropriato si intende che è @@ -1451,9 +1450,9 @@ per \param{cmd} sono: occorre essere il proprietario o il creatore della coda, oppure l'amministratore e lo stesso vale per \var{msg\_qbytes}. Infine solo l'amministratore (più precisamente un processo con la capacità - \itindex{capability} \const{CAP\_IPC\_RESOURCE}) ha la facoltà di - incrementarne il valore a limiti superiori a \const{MSGMNB}. Se eseguita con - successo la funzione aggiorna anche il campo \var{msg\_ctime}. + \const{CAP\_IPC\_RESOURCE}) ha la facoltà di incrementarne il valore a + limiti superiori a \const{MSGMNB}. Se eseguita con successo la funzione + aggiorna anche il campo \var{msg\_ctime}. \end{basedescript} A questi tre valori, che sono quelli previsti dallo standard, su Linux se ne @@ -1845,14 +1844,13 @@ successivo potrebbe ricevere un messaggio non indirizzato a lui. I semafori non sono propriamente meccanismi di intercomunicazione come \textit{pipe}, \textit{fifo} e code di messaggi, poiché non consentono di scambiare dati fra processi, ma servono piuttosto come meccanismi di -sincronizzazione o 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 infatti non è altro che un -contatore mantenuto nel kernel che determina se consentire o meno la -prosecuzione dell'esecuzione di un programma. In questo modo si può -controllare l'accesso ad una risorsa condivisa da più processi, associandovi -un semaforo che assicuri che non possa essere usata da più di un processo alla -volta. +sincronizzazione o di protezione per le \textsl{sezioni critiche} del codice +(si ricordi quanto detto in sez.~\ref{sec:proc_race_cond}). Un semaforo +infatti non è altro che un contatore mantenuto nel kernel che determina se +consentire o meno la prosecuzione dell'esecuzione di un programma. In questo +modo si può controllare l'accesso ad una risorsa condivisa da più processi, +associandovi un semaforo che assicuri che non possa essere usata da più di un +processo alla volta. Il concetto di semaforo è uno dei concetti base nella programmazione ed è assolutamente generico, così come del tutto generali sono modalità con cui lo @@ -2586,20 +2584,20 @@ di gestione del segmento di memoria condivisa in relazione al sistema della memoria virtuale. Il primo dei due flag è \const{SHM\_HUGETLB} che consente di richiedere la -creazione del segmento usando una \itindex{huge~page} \textit{huge page}, le -pagine di memoria di grandi dimensioni introdotte con il kernel 2.6 per -ottimizzare le prestazioni nei sistemi più recenti che hanno grandi quantità -di memoria. L'operazione è privilegiata e richiede che il processo abbia la -\itindex{capability} \textit{capability} \const{CAP\_IPC\_LOCK}. Questa -funzionalità è specifica di Linux e non è portabile. +creazione del segmento usando una \textit{huge page}, le pagine di memoria di +grandi dimensioni introdotte con il kernel 2.6 per ottimizzare le prestazioni +nei sistemi più recenti che hanno grandi quantità di memoria. L'operazione è +privilegiata e richiede che il processo abbia la \textit{capability} +\const{CAP\_IPC\_LOCK}. Questa funzionalità è specifica di Linux e non è +portabile. Il secondo flag aggiuntivo, introdotto a partire dal kernel 2.6.15, è \const{SHM\_NORESERVE}, ed ha lo stesso scopo del flag \const{MAP\_NORESERVE} di \func{mmap} (vedi sez.~\ref{sec:file_memory_map}): non vengono riservate -delle pagine di swap ad uso del meccanismo del \textit{copy on write} -\itindex{copy~on~write} per mantenere le modifiche fatte sul segmento. Questo -significa che caso di scrittura sul segmento quando non c'è più memoria -disponibile, si avrà l'emissione di un \signal{SIGSEGV}. +delle pagine di swap ad uso del meccanismo del \textit{copy on write} per +mantenere le modifiche fatte sul segmento. Questo significa che caso di +scrittura sul segmento quando non c'è più memoria disponibile, si avrà +l'emissione di un \signal{SIGSEGV}. Infine l'argomento \param{size} specifica la dimensione del segmento di memoria condivisa; il valore deve essere specificato in byte, ma verrà @@ -2773,19 +2771,18 @@ consentono di estendere le funzionalità, ovviamente non devono essere usati se si ha a cuore la portabilità. Questi comandi aggiuntivi sono: \begin{basedescript}{\desclabelwidth{2.2cm}\desclabelstyle{\nextlinelabel}} -\item[\const{SHM\_LOCK}] Abilita il \itindex{memory~locking} \textit{memory - locking} sul segmento di memoria condivisa, impedendo che la memoria usata - per il segmento venga salvata su disco dal meccanismo della memoria - virtuale. Come illustrato in sez.~\ref{sec:proc_mem_lock} fino al kernel - 2.6.9 solo l'amministratore poteva utilizzare questa capacità,\footnote{che - richiedeva la \textit{capability} \const{CAP\_IPC\_LOCK}.} a partire dal - dal kernel 2.6.10 anche gli utenti normali possono farlo fino al limite - massimo determinato da \const{RLIMIT\_MEMLOCK} (vedi +\item[\const{SHM\_LOCK}] Abilita il \textit{memory locking} sul segmento di + memoria condivisa, impedendo che la memoria usata per il segmento venga + salvata su disco dal meccanismo della memoria virtuale. Come illustrato in + sez.~\ref{sec:proc_mem_lock} fino al kernel 2.6.9 solo l'amministratore + poteva utilizzare questa capacità,\footnote{che richiedeva la + \textit{capability} \const{CAP\_IPC\_LOCK}.} a partire dal dal kernel + 2.6.10 anche gli utenti normali possono farlo fino al limite massimo + determinato da \const{RLIMIT\_MEMLOCK} (vedi sez.~\ref{sec:sys_resource_limit}). -\item[\const{SHM\_UNLOCK}] Disabilita il \itindex{memory~locking} - \textit{memory locking} sul segmento di memoria condivisa. Fino al kernel - 2.6.9 solo l'amministratore poteva utilizzare questo comando in - corrispondenza di un segmento da lui bloccato. +\item[\const{SHM\_UNLOCK}] Disabilita il \textit{memory locking} sul segmento + di memoria condivisa. Fino al kernel 2.6.9 solo l'amministratore poteva + utilizzare questo comando in corrispondenza di un segmento da lui bloccato. \end{basedescript} A questi due, come per \func{msgctl} e \func{semctl}, si aggiungono tre @@ -2816,7 +2813,7 @@ il suo prototipo è: } {La funzione ritorna l'indirizzo del segmento in caso di successo e $-1$ (in - un cast a \type{void *}) per un errore, nel qual caso \var{errno} assumerà + un cast a \ctyp{void *}) per un errore, nel qual caso \var{errno} assumerà uno dei valori: \begin{errlist} \item[\errcode{EACCES}] il processo non ha i privilegi per accedere al @@ -2881,12 +2878,12 @@ indirizzo come arrotondamento. L'uso di \const{SHM\_RDONLY} permette di agganciare il segmento in sola lettura (si ricordi che anche le pagine di memoria hanno dei permessi), in tal -caso un tentativo di scrivere sul segmento comporterà una -\itindex{segment~violation} violazione di accesso con l'emissione di un -segnale di \signal{SIGSEGV}. Il comportamento usuale di \func{shmat} è quello -di agganciare il segmento con l'accesso in lettura e scrittura (ed il processo -deve aver questi permessi in \var{shm\_perm}), non è prevista la possibilità -di agganciare un segmento in sola scrittura. +caso un tentativo di scrivere sul segmento comporterà una violazione di +accesso con l'emissione di un segnale di \signal{SIGSEGV}. Il comportamento +usuale di \func{shmat} è quello di agganciare il segmento con l'accesso in +lettura e scrittura (ed il processo deve aver questi permessi in +\var{shm\_perm}), non è prevista la possibilità di agganciare un segmento in +sola scrittura. Infine \const{SHM\_REMAP} è una estensione specifica di Linux (quindi non portabile) che indica che la mappatura del segmento deve rimpiazzare ogni @@ -3035,10 +3032,10 @@ ricavare la parte di informazione che interessa. In fig.~\ref{fig:ipc_dirmonitor_main} si è riportata la sezione principale del corpo del programma server, insieme alle definizioni delle altre funzioni -usate nel programma e delle \index{variabili!globali} variabili globali, -omettendo tutto quello che riguarda la gestione delle opzioni e la stampa -delle istruzioni di uso a video; al solito il codice completo si trova con i -sorgenti allegati nel file \file{DirMonitor.c}. +usate nel programma e delle variabili globali, omettendo tutto quello che +riguarda la gestione delle opzioni e la stampa delle istruzioni di uso a +video; al solito il codice completo si trova con i sorgenti allegati nel file +\file{DirMonitor.c}. \begin{figure}[!htbp] \footnotesize \centering @@ -3050,11 +3047,11 @@ sorgenti allegati nel file \file{DirMonitor.c}. \label{fig:ipc_dirmonitor_main} \end{figure} -Il programma usa delle \index{variabili!globali} variabili globali -(\texttt{\small 2-14}) per mantenere i valori relativi agli oggetti usati per -la comunicazione inter-processo; si è definita inoltre una apposita struttura -\struct{DirProp} che contiene i dati relativi alle proprietà che si vogliono -mantenere nella memoria condivisa, per l'accesso da parte dei client. +Il programma usa delle variabili globali (\texttt{\small 2-14}) per mantenere +i valori relativi agli oggetti usati per la comunicazione inter-processo; si è +definita inoltre una apposita struttura \struct{DirProp} che contiene i dati +relativi alle proprietà che si vogliono mantenere nella memoria condivisa, per +l'accesso da parte dei client. Il programma, dopo la sezione, omessa, relativa alla gestione delle opzioni da riga di comando (che si limitano alla eventuale stampa di un messaggio di @@ -3067,12 +3064,11 @@ con un messaggio di errore. Poi, per verificare che l'argomento specifichi effettivamente una directory, si esegue (\texttt{\small 24-26}) su di esso una \func{chdir}, uscendo immediatamente in caso di errore. Questa funzione serve anche per impostare -la \index{directory~di~lavoro} directory di lavoro del programma nella -directory da tenere sotto controllo, in vista del successivo uso della -funzione \func{daemon}. Si noti come si è potuta fare questa scelta, -nonostante le indicazioni illustrate in sez.~\ref{sec:sess_daemon}, per il -particolare scopo del programma, che necessita comunque di restare all'interno -di una directory. +la directory di lavoro del programma nella directory da tenere sotto +controllo, in vista del successivo uso della funzione \func{daemon}. Si noti +come si è potuta fare questa scelta, nonostante le indicazioni illustrate in +sez.~\ref{sec:sess_daemon}, per il particolare scopo del programma, che +necessita comunque di restare all'interno di una directory. Infine (\texttt{\small 27-29}) si installano i gestori per i vari segnali di terminazione che, avendo a che fare con un programma che deve essere eseguito @@ -3101,9 +3097,9 @@ intercomunicazione il programma entra nel ciclo principale (\texttt{\small Il primo passo (\texttt{\small 41}) è eseguire \func{daemon} per proseguire con l'esecuzione in background come si conviene ad un programma demone; si noti che si è mantenuta, usando un valore non nullo del primo argomento, la -\index{directory~di~lavoro} directory di lavoro corrente. Una volta che il -programma è andato in background l'esecuzione prosegue all'interno di un ciclo -infinito (\texttt{\small 42-48}). +directory di lavoro corrente. Una volta che il programma è andato in +background l'esecuzione prosegue all'interno di un ciclo infinito +(\texttt{\small 42-48}). Si inizia (\texttt{\small 43}) bloccando il mutex con \func{MutexLock} per poter accedere alla memoria condivisa (la funzione si bloccherà @@ -3133,11 +3129,11 @@ esse la funzione \func{ComputeValues}, che esegue tutti i calcoli necessari. Il codice di quest'ultima è riportato in fig.~\ref{fig:ipc_dirmonitor_sub}. -Come si vede la funzione (\texttt{\small 2-16}) è molto semplice e si limita -a chiamare (\texttt{\small 5}) la funzione \func{stat} sul file indicato da +Come si vede la funzione (\texttt{\small 2-16}) è molto semplice e si limita a +chiamare (\texttt{\small 5}) la funzione \func{stat} sul file indicato da ciascuna voce, per ottenerne i dati, che poi utilizza per incrementare i vari -contatori nella memoria condivisa, cui accede grazie alla -\index{variabili!globali} variabile globale \var{shmptr}. +contatori nella memoria condivisa, cui accede grazie alla variabile globale +\var{shmptr}. Dato che la funzione è chiamata da \myfunc{dir\_scan}, si è all'interno del ciclo principale del programma, con un mutex acquisito, perciò non è @@ -3345,12 +3341,12 @@ directory, \file{/var/lock}, nella standardizzazione del \textit{Filesystem 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 \itindex{race~condition} \textit{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 lock (e della risorsa ad esso associata) mentre -il rilascio si può eseguire con una chiamata ad \func{unlink}. + possibilità di una \textit{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 +lock (e della risorsa ad esso associata) mentre il rilascio si può eseguire +con una chiamata ad \func{unlink}. Un esempio dell'uso di questa funzione è mostrato dalle funzioni \func{LockFile} ed \func{UnlockFile} riportate in fig.~\ref{fig:ipc_file_lock} @@ -3789,9 +3785,8 @@ dei limiti sono: valore massimo è \const{HARD\_MAX} che vale \code{(131072/sizeof(void *))}, ed il valore minimo 1 (ma era 10 per i kernel precedenti il 2.6.28). Questo limite viene ignorato per i processi con privilegi amministrativi (più - precisamente con la \itindex{capability} \textit{capability} - \const{CAP\_SYS\_RESOURCE}) ma \const{HARD\_MAX} resta comunque non - superabile. + precisamente con la \textit{capability} \const{CAP\_SYS\_RESOURCE}) ma + \const{HARD\_MAX} resta comunque non superabile. \item[\sysctlfile{fs/mqueue/msgsize\_max}] Indica il valore massimo della dimensione in byte di un messaggio sulla coda ed agisce come limite @@ -3799,14 +3794,14 @@ dei limiti sono: suo valore di default è 8192. Il valore massimo è 1048576 ed il valore minimo 128 (ma per i kernel precedenti il 2.6.28 detti limiti erano rispettivamente \const{INT\_MAX} e 8192). Questo limite viene ignorato dai - processi con privilegi amministrativi (con la \itindex{capability} - \textit{capability} \const{CAP\_SYS\_RESOURCE}). + processi con privilegi amministrativi (con la \textit{capability} + \const{CAP\_SYS\_RESOURCE}). \item[\sysctlfile{fs/mqueue/queues\_max}] Indica il numero massimo di code di messaggi creabili in totale sul sistema, il valore di default è 256 ma si può usare un valore qualunque fra $0$ e \const{INT\_MAX}. Il limite non viene applicato ai processi con privilegi amministrativi (cioè con la - \itindex{capability} \textit{capability} \const{CAP\_SYS\_RESOURCE}). + \textit{capability} \const{CAP\_SYS\_RESOURCE}). \end{basedescript} @@ -4150,12 +4145,12 @@ che se si vuole mantenere il meccanismo di notifica occorre ripetere la registrazione chiamando nuovamente \func{mq\_notify} all'interno del gestore del segnale di notifica. A differenza della situazione simile che si aveva con i segnali non affidabili (l'argomento è stato affrontato in -\ref{sec:sig_semantics}) questa caratteristica non configura una -\itindex{race~condition} \textit{race condition} perché l'invio di un segnale -avviene solo se la coda è vuota; pertanto se si vuole evitare di correre il -rischio di perdere eventuali ulteriori segnali inviati nel lasso di tempo che -occorre per ripetere la richiesta di notifica basta avere cura di eseguire -questa operazione prima di estrarre i messaggi presenti dalla coda. +\ref{sec:sig_semantics}) questa caratteristica non configura una \textit{race + condition} perché l'invio di un segnale avviene solo se la coda è vuota; +pertanto se si vuole evitare di correre il rischio di perdere eventuali +ulteriori segnali inviati nel lasso di tempo che occorre per ripetere la +richiesta di notifica basta avere cura di eseguire questa operazione prima di +estrarre i messaggi presenti dalla coda. L'invio del segnale di notifica avvalora alcuni campi di informazione restituiti al gestore attraverso la struttura \struct{siginfo\_t} (definita in @@ -4764,12 +4759,11 @@ il semaforo deve essere utilizzato dai \itindex{thread} \textit{thread} di uno stesso processo (con un valore nullo) o condiviso fra processi diversi (con un valore non nullo). -Qualora il semaforo debba essere condiviso dai \itindex{thread} -\textit{thread} di uno stesso processo (nel qual caso si parla di -\textit{thread-shared semaphore}), occorrerà che \param{sem} sia l'indirizzo -di una variabile visibile da tutti i \itindex{thread} \textit{thread}, si -dovrà usare cioè una \index{variabili!globali} variabile globale o una -variabile allocata dinamicamente nello \itindex{heap} \textit{heap}. +Qualora il semaforo debba essere condiviso dai \textit{thread} di uno stesso +processo (nel qual caso si parla di \textit{thread-shared semaphore}), +occorrerà che \param{sem} sia l'indirizzo di una variabile visibile da tutti i +\textit{thread}, si dovrà usare cioè una variabile globale o una variabile +allocata dinamicamente nello \textit{heap}. Qualora il semaforo debba essere condiviso fra più processi (nel qual caso si parla di \textit{process-shared semaphore}) la sola scelta possibile per @@ -4850,9 +4844,9 @@ dall'altro programma prima di averla finita di stampare. La parte iniziale del programma contiene le definizioni (\texttt{\small 1-8}) del gestore del segnale usato per liberare le risorse utilizzate, delle -\index{variabili!globali} variabili globali contenenti i nomi di default del -segmento di memoria condivisa e del semaforo (il default scelto è -\texttt{messages}), e delle altre variabili utilizzate dal programma. +variabili globali contenenti i nomi di default del segmento di memoria +condivisa e del semaforo (il default scelto è \texttt{messages}), e delle +altre variabili utilizzate dal programma. Come prima istruzione (\texttt{\small 10}) si è provveduto ad installare un gestore di segnale che consentirà di effettuare le operazioni di pulizia @@ -4881,12 +4875,12 @@ notazione ottale). Infine il semaforo verrà inizializzato ad un valore nullo A questo punto (\texttt{\small 22}) si potrà inizializzare il messaggio posto nel segmento di memoria condivisa usando la stringa passata come argomento al programma. Essendo il semaforo stato creato già bloccato non ci si dovrà -preoccupare di eventuali \itindex{race~condition} \textit{race condition} -qualora il programma di modifica del messaggio venisse lanciato proprio in -questo momento. Una volta inizializzato il messaggio occorrerà però -rilasciare il semaforo (\texttt{\small 24-27}) per consentirne l'uso; in -tutte queste operazioni si provvederà ad uscire dal programma con un opportuno -messaggio in caso di errore. +preoccupare di eventuali \textit{race condition} qualora il programma di +modifica del messaggio venisse lanciato proprio in questo momento. Una volta +inizializzato il messaggio occorrerà però rilasciare il semaforo +(\texttt{\small 24-27}) per consentirne l'uso; in tutte queste operazioni si +provvederà ad uscire dal programma con un opportuno messaggio in caso di +errore. Una volta completate le inizializzazioni il ciclo principale del programma (\texttt{\small 29-47}) viene ripetuto indefinitamente (\texttt{\small 29}) @@ -4957,8 +4951,8 @@ argomento. Una volta completate con successo le precedenti inizializzazioni, il passo seguente (\texttt{\small 21-24}) è quello di acquisire il semaforo, dopo di che sarà possibile eseguire la sostituzione del messaggio (\texttt{\small 25}) -senza incorrere in possibili \itindex{race~condition} \textit{race condition} -con la stampa dello stesso da parte di \file{message\_getter}. +senza incorrere in possibili \textit{race condition} con la stampa dello +stesso da parte di \file{message\_getter}. Una volta effettuata la modifica viene stampato (\texttt{\small 26}) il tempo di attesa impostato con l'opzione ``\texttt{-t}'' dopo di che (\texttt{\small @@ -5085,10 +5079,10 @@ testo alla terminazione di quest'ultimo. % LocalWords: SysV capability short RESOURCE INFO UNDEFINED EFBIG semtimedop % LocalWords: scan HUGETLB huge page NORESERVE copy RLIMIT MEMLOCK REMAP UTC % LocalWords: readmon Hierarchy defaults queues MSGQUEUE effective fstat +% LocalWords: fchown fchmod Epoch January %%% Local Variables: %%% mode: latex %%% TeX-master: "gapil" %%% End: -% LocalWords: fchown fchmod Epoch January