X-Git-Url: https://gapil.gnulinux.it/gitweb/?p=gapil.git;a=blobdiff_plain;f=ipc.tex;h=2fc13a8f67d44d6c99e325885e20937d8b4282e6;hp=91d38feb5ab5534d0928d7bdfb3402ae1fdc16e4;hb=fae1b357c38b50ce788f3f06f7153b1ce4ee57df;hpb=5afbcf1d6a84ab2a527859d8fd05b75a31e39736 diff --git a/ipc.tex b/ipc.tex index 91d38fe..2fc13a8 100644 --- a/ipc.tex +++ b/ipc.tex @@ -1,6 +1,6 @@ %% ipc.tex %% -%% Copyright (C) 2000-2015 Simone Piccardi. Permission is granted to +%% Copyright (C) 2000-2017 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", @@ -648,7 +648,7 @@ due volte, prima in lettura e poi in scrittura, per evitare di dover gestire all'interno del ciclo principale il caso in cui il server è in ascolto ma non ci sono client che effettuano richieste. Si ricordi infatti che quando una \textit{fifo} è aperta solo dal capo in lettura, l'esecuzione di \func{read} -ritorna con zero byte (si ha cioè una condizione di end-of-file). +ritorna con zero byte (si ha cioè una condizione di \textit{end-of-file}). Nel nostro caso la prima apertura si bloccherà fintanto che un qualunque client non apre a sua volta la \textit{fifo} nota in scrittura per effettuare @@ -954,7 +954,7 @@ Usando la stessa chiave due processi diversi possono ricavare l'identificatore associato ad un oggetto ed accedervi. Il problema che sorge a questo punto è come devono fare per accordarsi sull'uso di una stessa chiave. Se i processi sono \textsl{imparentati} la soluzione è relativamente semplice, in tal caso -infatti si può usare il valore speciale \texttt{IPC\_PRIVATE} per creare un +infatti si può usare il valore speciale \constd{IPC\_PRIVATE} per creare un nuovo oggetto nel processo padre, l'identificatore così ottenuto sarà disponibile in tutti i figli, e potrà essere passato come argomento attraverso una \func{exec}. @@ -1045,8 +1045,8 @@ il proprietario, il suo gruppo e tutti gli altri. Se però si vogliono usare le costanti simboliche di tab.~\ref{tab:file_mode_flags} occorrerà includere anche il file -\headfile{sys/stat.h}; alcuni sistemi definiscono le costanti \const{MSG\_R} -(il valore ottale \texttt{0400}) e \const{MSG\_W} (il valore ottale +\headfile{sys/stat.h}; alcuni sistemi definiscono le costanti \constd{MSG\_R} +(il valore ottale \texttt{0400}) e \constd{MSG\_W} (il valore ottale \texttt{0200}) per indicare i permessi base di lettura e scrittura per il proprietario, da utilizzare, con gli opportuni shift, pure per il gruppo e gli altri. In Linux, visto la loro scarsa utilità, queste costanti non sono @@ -1128,7 +1128,7 @@ Il sistema dispone sempre di un numero fisso di oggetti di IPC, fino al kernel relativi al \textit{SysV-IPC}) solo con una ricompilazione del kernel. A partire dal kernel 2.4.x è possibile cambiare questi valori a sistema attivo scrivendo sui file \sysctlrelfile{kernel}{shmmni}, -\sysctlrelfile{kernel}{msgmni} e \sysctlrelfile{kernel}{sem} di +\sysctlrelfile{kernel}{msgmni} e \sysctlrelfiled{kernel}{sem} di \file{/proc/sys/kernel} o con l'uso di \func{sysctl}. \begin{figure}[!htb] @@ -1151,7 +1151,7 @@ numero di oggetti presenti viene sommato il valore corrente del campo Questo in realtà è quanto avveniva fino ai kernel della serie 2.2, dalla serie 2.4 viene usato lo stesso fattore di moltiplicazione per qualunque tipo di -oggetto, utilizzando il valore dalla costante \const{IPCMNI} (definita in +oggetto, utilizzando il valore dalla costante \constd{IPCMNI} (definita in \file{include/linux/ipc.h}), che indica il limite massimo complessivo per il numero di tutti gli oggetti presenti nel \textit{SysV-IPC}, ed il cui default è 32768. Si evita così il riutilizzo degli stessi numeri, e si fa sì che @@ -1267,10 +1267,10 @@ validi. Se invece si vuole creare una nuova coda di messaggi \param{flag} non può essere nullo e deve essere fornito come maschera binaria, impostando il bit -corrispondente al valore \const{IPC\_CREAT}. In questo caso i nove bit meno +corrispondente al valore \constd{IPC\_CREAT}. In questo caso i nove bit meno significativi di \param{flag} saranno usati come permessi per il nuovo oggetto, secondo quanto illustrato in sez.~\ref{sec:ipc_sysv_access_control}. -Se si imposta anche il bit corrispondente a \const{IPC\_EXCL} la funzione avrà +Se si imposta anche il bit corrispondente a \constd{IPC\_EXCL} la funzione avrà successo solo se l'oggetto non esiste già, fallendo con un errore di \errcode{EEXIST} altrimenti. @@ -1292,11 +1292,11 @@ creazione di una nuova coda. & \textbf{Significato} \\ \hline \hline - \const{MSGMNI}& 16& \file{msgmni} & Numero massimo di code di + \constd{MSGMNI}& 16& \file{msgmni} & Numero massimo di code di messaggi.\\ - \const{MSGMAX}& 8192& \file{msgmax} & Dimensione massima di un singolo + \constd{MSGMAX}& 8192& \file{msgmax} & Dimensione massima di un singolo messaggio.\\ - \const{MSGMNB}&16384& \file{msgmnb} & Dimensione massima del contenuto di + \constd{MSGMNB}&16384& \file{msgmnb} & Dimensione massima del contenuto di una coda.\\ \hline \end{tabular} @@ -1308,8 +1308,8 @@ Le code di messaggi sono caratterizzate da tre limiti fondamentali, un tempo definiti staticamente e corrispondenti alle prime tre costanti riportate in tab.~\ref{tab:ipc_msg_limits}. Come accennato però con tutte le versioni più recenti del kernel con Linux è possibile modificare questi limiti attraverso -l'uso di \func{sysctl} o scrivendo nei file \sysctlrelfile{kernel}{msgmax}, -\sysctlrelfile{kernel}{msgmnb} e \sysctlrelfile{kernel}{msgmni} di +l'uso di \func{sysctl} o scrivendo nei file \sysctlrelfiled{kernel}{msgmax}, +\sysctlrelfiled{kernel}{msgmnb} e \sysctlrelfiled{kernel}{msgmni} di \file{/proc/sys/kernel/}. \itindbeg{linked~list} @@ -1435,17 +1435,17 @@ comportamento della funzione dipende dal valore dell'argomento \param{cmd}, che specifica il tipo di azione da eseguire. I valori possibili per \param{cmd} sono: \begin{basedescript}{\desclabelwidth{1.6cm}\desclabelstyle{\nextlinelabel}} -\item[\const{IPC\_STAT}] Legge le informazioni riguardo la coda nella +\item[\constd{IPC\_STAT}] Legge le informazioni riguardo la coda nella struttura \struct{msqid\_ds} indicata da \param{buf}. Occorre avere il permesso di lettura sulla coda. -\item[\const{IPC\_RMID}] Rimuove la coda, cancellando tutti i dati, con +\item[\constd{IPC\_RMID}] Rimuove la coda, cancellando tutti i dati, con effetto immediato. Tutti i processi che cercheranno di accedere alla coda riceveranno un errore di \errcode{EIDRM}, e tutti processi in attesa su funzioni di lettura o di scrittura sulla coda saranno svegliati ricevendo il medesimo errore. Questo comando può essere eseguito solo da un processo con \ids{UID} effettivo corrispondente al creatore o al proprietario della coda, o all'amministratore. -\item[\const{IPC\_SET}] Permette di modificare i permessi ed il proprietario +\item[\constd{IPC\_SET}] Permette di modificare i permessi ed il proprietario della coda, ed il limite massimo sulle dimensioni del totale dei messaggi in essa contenuti (\var{msg\_qbytes}). I valori devono essere passati in una struttura \struct{msqid\_ds} puntata da \param{buf}. Per modificare i @@ -1459,8 +1459,8 @@ per \param{cmd} sono: \end{basedescript} A questi tre valori, che sono quelli previsti dallo standard, su Linux se ne -affiancano altri tre (\const{IPC\_INFO}, \const{MSG\_STAT} e -\const{MSG\_INFO}) introdotti ad uso del programma \cmd{ipcs} per ottenere le +affiancano altri tre (\constd{IPC\_INFO}, \constd{MSG\_STAT} e +\constd{MSG\_INFO}) introdotti ad uso del programma \cmd{ipcs} per ottenere le informazioni generali relative alle risorse usate dalle code di messaggi. Questi potranno essere modificati o rimossi in favore dell'uso di \texttt{/proc}, per cui non devono essere usati e non li tratteremo. @@ -1533,7 +1533,7 @@ 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 fig.~\ref{fig:ipc_msbuf}, \param{msgsz} -dovrà essere pari a \const{LENGTH}). +dovrà essere pari a \var{LENGTH}). Per capire meglio il funzionamento della funzione riprendiamo in considerazione la struttura della coda illustrata in @@ -1550,7 +1550,7 @@ della funzione. Di norma, quando si specifica un valore nullo, la funzione ritorna immediatamente a meno che si sia ecceduto il valore di \var{msg\_qbytes}, o il limite di sistema sul numero di messaggi, nel qual caso si blocca. Se si specifica per \param{flag} il valore -\const{IPC\_NOWAIT} la funzione opera in modalità non-bloccante, ed in questi +\constd{IPC\_NOWAIT} la funzione opera in modalità non-bloccante, ed in questi casi ritorna immediatamente con un errore di \errcode{EAGAIN}. Se non si specifica \const{IPC\_NOWAIT} la funzione resterà bloccata fintanto @@ -1602,11 +1602,11 @@ scrivendolo sulla struttura puntata da \param{msgp}, che dovrà avere un formato analogo a quello di fig.~\ref{fig:ipc_msbuf}. Una volta estratto, il messaggio sarà rimosso dalla coda. L'argomento \param{msgsz} indica la lunghezza massima del testo del messaggio (equivalente al valore del parametro -\const{LENGTH} nell'esempio di fig.~\ref{fig:ipc_msbuf}). +\var{LENGTH} nell'esempio di fig.~\ref{fig:ipc_msbuf}). Se il testo del messaggio ha lunghezza inferiore a \param{msgsz} esso viene rimosso dalla coda; in caso contrario, se \param{msgflg} è impostato a -\const{MSG\_NOERROR}, il messaggio viene troncato e la parte in eccesso viene +\constd{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 \errcode{E2BIG}. @@ -1630,7 +1630,7 @@ coda, è quello meno recente); in particolare: 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 \const{MSG\_NOERROR}, sono possibili altri due -valori: \const{MSG\_EXCEPT}, che permette, quando \param{msgtyp} è positivo, +valori: \constd{MSG\_EXCEPT}, che permette, quando \param{msgtyp} è positivo, di leggere il primo messaggio nella coda con tipo diverso da \param{msgtyp}, e \const{IPC\_NOWAIT} che causa il ritorno immediato della funzione quando non ci sono messaggi sulla coda. @@ -1669,8 +1669,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 \itindex{polling} \textit{polling} che esegua un ciclo di attesa su -ciascuna di esse. +di \textit{polling} che esegua un ciclo di attesa su ciascuna di esse. Come esempio dell'uso delle code di messaggi possiamo riscrivere il nostro server di \textit{fortunes} usando queste al posto delle \textit{fifo}. In @@ -2021,17 +2020,17 @@ direttamente nel file \sysctlfile{kernel/sem}. \textbf{Costante} & \textbf{Valore} & \textbf{Significato} \\ \hline \hline - \const{SEMMNI}& 128 & Numero massimo di insiemi di semafori.\\ - \const{SEMMSL}& 250 & Numero massimo di semafori per insieme.\\ - \const{SEMMNS}&\const{SEMMNI}*\const{SEMMSL}& Numero massimo di semafori - nel sistema.\\ - \const{SEMVMX}& 32767 & Massimo valore per un semaforo.\\ - \const{SEMOPM}& 32 & Massimo numero di operazioni per chiamata a - \func{semop}. \\ - \const{SEMMNU}&\const{SEMMNS}& Massimo numero di strutture di ripristino.\\ - \const{SEMUME}&\const{SEMOPM}& Massimo numero di voci di ripristino.\\ - \const{SEMAEM}&\const{SEMVMX}& Valore massimo per l'aggiustamento - all'uscita. \\ + \constd{SEMMNI}& 128 & Numero massimo di insiemi di semafori.\\ + \constd{SEMMSL}& 250 & Numero massimo di semafori per insieme.\\ + \constd{SEMMNS}&\const{SEMMNI}*\const{SEMMSL}& Numero massimo di semafori + nel sistema.\\ + \constd{SEMVMX}& 32767 & Massimo valore per un semaforo.\\ + \constd{SEMOPM}& 32 & Massimo numero di operazioni per chiamata a + \func{semop}. \\ + \constd{SEMMNU}&\const{SEMMNS}& Massimo numero di strutture di ripristino.\\ + \constd{SEMUME}&\const{SEMOPM}& Massimo numero di voci di ripristino.\\ + \constd{SEMAEM}&\const{SEMVMX}& Valore massimo per l'aggiustamento + all'uscita. \\ \hline \end{tabular} \caption{Valori delle costanti associate ai limiti degli insiemi di @@ -2100,7 +2099,7 @@ Nelle versioni più vecchie delle \acr{glibc} questa unione veniva definita in \file{sys/sem.h}, ma nelle versioni più recenti questo non avviene più in quanto lo standard POSIX.1-2001 richiede che sia sempre definita a cura del chiamante. In questa seconda evenienza le \acr{glibc} definiscono però la -macro \macro{\_SEM\_SEMUN\_UNDEFINED} che può essere usata per controllare la +macro \macrod{\_SEM\_SEMUN\_UNDEFINED} che può essere usata per controllare la situazione. Come già accennato sia il comportamento della funzione che il numero di @@ -2127,40 +2126,40 @@ i seguenti: \var{sem\_ctime}. L'\ids{UID} effettivo del processo deve corrispondere o al creatore o al proprietario dell'insieme, o all'amministratore. L'argomento \param{semnum} viene ignorato. -\item[\const{GETALL}] Restituisce il valore corrente di ciascun semaforo +\item[\constd{GETALL}] Restituisce il valore corrente di ciascun semaforo dell'insieme (corrispondente al campo \var{semval} di \struct{sem}) nel vettore indicato da \param{arg.array}. Occorre avere il permesso di lettura. L'argomento \param{semnum} viene ignorato. -\item[\const{GETNCNT}] Restituisce come valore di ritorno della funzione il +\item[\constd{GETNCNT}] Restituisce come valore di ritorno della funzione il numero di processi in attesa che il semaforo \param{semnum} dell'insieme \param{semid} venga incrementato (corrispondente al campo \var{semncnt} di \struct{sem}). Va invocata con tre argomenti. Occorre avere il permesso di lettura. -\item[\const{GETPID}] Restituisce come valore di ritorno della funzione il +\item[\constd{GETPID}] Restituisce come valore di ritorno della funzione il \ids{PID} dell'ultimo processo che ha compiuto una operazione sul semaforo \param{semnum} dell'insieme \param{semid} (corrispondente al campo \var{sempid} di \struct{sem}). Va invocata con tre argomenti. Occorre avere il permesso di lettura. -\item[\const{GETVAL}] Restituisce come valore di ritorno della funzione il il +\item[\constd{GETVAL}] Restituisce come valore di ritorno della funzione il il valore corrente del semaforo \param{semnum} dell'insieme \param{semid} (corrispondente al campo \var{semval} di \struct{sem}). Va invocata con tre argomenti. Occorre avere il permesso di lettura. -\item[\const{GETZCNT}] Restituisce come valore di ritorno della funzione il +\item[\constd{GETZCNT}] Restituisce come valore di ritorno della funzione il numero di processi in attesa che il valore del semaforo \param{semnum} dell'insieme \param{semid} diventi nullo (corrispondente al campo \var{semncnt} di \struct{sem}). Va invocata con tre argomenti. Occorre avere il permesso di lettura. -\item[\const{SETALL}] Inizializza il valore di tutti i semafori dell'insieme, +\item[\constd{SETALL}] Inizializza il valore di tutti i semafori dell'insieme, aggiornando il campo \var{sem\_ctime} di \struct{semid\_ds}. I valori devono essere passati nel vettore indicato da \param{arg.array}. Si devono avere i privilegi di scrittura. L'argomento \param{semnum} viene ignorato. -\item[\const{SETVAL}] Inizializza il semaforo \param{semnum} al valore passato +\item[\constd{SETVAL}] Inizializza il semaforo \param{semnum} al valore passato dall'argomento \param{arg.val}, aggiornando il campo \var{sem\_ctime} di \struct{semid\_ds}. Si devono avere i privilegi di scrittura. \end{basedescript} Come per \func{msgctl} esistono tre ulteriori valori, \const{IPC\_INFO}, -\const{SEM\_STAT} e \const{SEM\_INFO}, specifici di Linux e fuori da ogni +\constd{SEM\_STAT} e \constd{SEM\_INFO}, specifici di Linux e fuori da ogni standard, creati specificamente ad uso del comando \cmd{ipcs}. Dato che anche questi potranno essere modificati o rimossi, non devono essere utilizzati e pertanto non li tratteremo. @@ -2305,7 +2304,7 @@ un valore nullo di \var{sem\_num}. Il campo \var{sem\_flg} è un flag, mantenuto come maschera binaria, per il quale possono essere impostati i due valori \const{IPC\_NOWAIT} e -\const{SEM\_UNDO}. Impostando \const{IPC\_NOWAIT} si fa si che in tutti quei +\constd{SEM\_UNDO}. Impostando \const{IPC\_NOWAIT} si fa si che in tutti quei casi in cui l'esecuzione di una operazione richiederebbe di porre il processo vada nello stato di \textit{sleep}, invece di bloccarsi \func{semop} ritorni immediatamente (abortendo così le eventuali operazioni restanti) con un errore @@ -2542,7 +2541,7 @@ controllare il valore dei mutex prima di proseguire in una operazione di sblocco non servirebbe comunque, dato che l'operazione non sarebbe atomica. Vedremo in sez.~\ref{sec:ipc_lock_file} come sia possibile ottenere un'interfaccia analoga a quella appena illustrata, senza incorrere in questi -problemi, usando il \itindex{file~locking} \textit{file locking}. +problemi, usando il \textit{file locking}. \subsection{Memoria condivisa} @@ -2588,7 +2587,7 @@ l'argomento \param{flag}, specifici di \func{shmget}, attinenti alle modalità 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 +Il primo dei due flag è \constd{SHM\_HUGETLB} che consente di richiedere la 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 è @@ -2597,7 +2596,7 @@ privilegiata e richiede che il processo abbia la \textit{capability} 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} +\constd{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} per mantenere le modifiche fatte sul segmento. Questo significa che caso di @@ -2686,27 +2685,27 @@ che permettono di cambiarne il valore. & \textbf{Significato} \\ \hline \hline - \const{SHMALL}& 0x200000&\sysctlrelfile{kernel}{shmall} - & Numero massimo di pagine che - possono essere usate per i segmenti di - memoria condivisa.\\ - \const{SHMMAX}&0x2000000&\sysctlrelfile{kernel}{shmmax} - & Dimensione massima di un segmento di memoria - condivisa.\\ - \const{SHMMNI}& 4096&\sysctlrelfile{kernel}{msgmni} - & Numero massimo di segmenti di memoria condivisa + \constd{SHMALL}& 0x200000&\sysctlrelfiled{kernel}{shmall} + & Numero massimo di pagine che + possono essere usate per i segmenti di + memoria condivisa.\\ + \constd{SHMMAX}&0x2000000&\sysctlrelfiled{kernel}{shmmax} + & Dimensione massima di un segmento di memoria + condivisa.\\ + \constd{SHMMNI}& 4096&\sysctlrelfiled{kernel}{shmmni} + & Numero massimo di segmenti di memoria condivisa presenti nel kernel.\\ - \const{SHMMIN}& 1& --- & Dimensione minima di un segmento di - memoria condivisa.\\ - \const{SHMLBA}&\const{PAGE\_SIZE}&--- & Limite inferiore per le dimensioni - minime di un segmento (deve essere - allineato alle dimensioni di una - pagina di memoria).\\ - \const{SHMSEG}& --- & --- & Numero massimo di segmenti di - memoria condivisa per ciascun - processo (l'implementazione non - prevede l'esistenza di questo - limite).\\ + \constd{SHMMIN}& 1& --- & Dimensione minima di un segmento di + memoria condivisa.\\ + \constd{SHMLBA}&\const{PAGE\_SIZE}&--- & Limite inferiore per le dimensioni + minime di un segmento (deve essere + allineato alle dimensioni di una + pagina di memoria).\\ + \constd{SHMSEG}& --- & --- & Numero massimo di segmenti di + memoria condivisa per ciascun + processo (l'implementazione non + prevede l'esistenza di questo + limite).\\ \hline @@ -2776,7 +2775,7 @@ 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 \textit{memory locking} sul segmento di +\item[\constd{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 @@ -2785,13 +2784,13 @@ si ha a cuore la portabilità. Questi comandi aggiuntivi sono: 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 \textit{memory locking} sul segmento +\item[\constd{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 -ulteriori valori, \const{IPC\_INFO}, \const{MSG\_STAT} e \const{MSG\_INFO}, +ulteriori valori, \const{IPC\_INFO}, \constd{SHM\_STAT} e \constd{SHM\_INFO}, introdotti ad uso del programma \cmd{ipcs} per ottenere le informazioni generali relative alle risorse usate dai segmenti di memoria condivisa. Dato che potranno essere modificati o rimossi in favore dell'uso di \texttt{/proc}, @@ -2874,14 +2873,14 @@ momento sono sono tre e sono identificati dalle costanti \const{SHM\_RND}, \const{SHM\_RDONLY} e \const{SHM\_REMAP} che vanno combinate con un OR aritmetico. -Specificando \const{SHM\_RND} si evita che \func{shmat} ritorni un errore +Specificando \constd{SHM\_RND} si evita che \func{shmat} ritorni un errore quando \param{shmaddr} non è allineato ai confini di una pagina. Si può quindi usare un valore qualunque per \param{shmaddr}, e il segmento verrà comunque agganciato, ma al più vicino multiplo di \const{SHMLBA}; il nome della costante sta infatti per \textit{rounded}, e serve per specificare un indirizzo come arrotondamento. -L'uso di \const{SHM\_RDONLY} permette di agganciare il segmento in sola +L'uso di \constd{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 violazione di accesso con l'emissione di un segnale di \signal{SIGSEGV}. Il comportamento @@ -2890,13 +2889,13 @@ 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 +Infine \constd{SHM\_REMAP} è una estensione specifica di Linux (quindi non portabile) che indica che la mappatura del segmento deve rimpiazzare ogni precedente mappatura esistente nell'intervallo iniziante all'indirizzo \param{shmaddr} e di dimensione pari alla lunghezza del segmento. In condizioni normali questo tipo di richiesta fallirebbe con un errore di \errval{EINVAL}. Ovviamente usando \const{SHM\_REMAP} -l'argomento \param{shmaddr} non può essere nullo. +l'argomento \param{shmaddr} non può essere nullo. In caso di successo la funzione \func{shmat} aggiorna anche i seguenti campi della struttura \struct{shmid\_ds}: @@ -3391,8 +3390,8 @@ 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 \itindex{polling} -\textit{polling}, ed è quindi molto inefficiente. +può essere eseguito solo con una tecnica di \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 @@ -3409,15 +3408,14 @@ accedere alla seriale si limita a segnalare che la risorsa non è disponibile. Dato che i file di lock presentano gli inconvenienti illustrati in precedenza, la tecnica alternativa di sincronizzazione più comune è quella di fare ricorso -al \itindex{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 \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. +al \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} +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 @@ -3432,17 +3430,16 @@ leggermente più lento. \includecodesample{listati/MutexLocking.c} \end{minipage} \normalsize - \caption{Il codice delle funzioni che permettono per la gestione dei - \textit{mutex} con il \itindex{file~locking} \textit{file locking}.} + \caption{Il codice delle funzioni che permettono per la gestione dei + \textit{mutex} con il \textit{file locking}.} \label{fig:ipc_flock_mutex} \end{figure} Il codice delle varie funzioni usate per implementare un mutex utilizzando il -\textit{file locking} \itindex{file~locking} è riportato in -fig.~\ref{fig:ipc_flock_mutex}; si è mantenuta volutamente una struttura -analoga alle precedenti funzioni che usano i semafori, anche se le due -interfacce non possono essere completamente equivalenti, specie per quanto -riguarda la rimozione del mutex. +\textit{file locking} è riportato in fig.~\ref{fig:ipc_flock_mutex}; si è +mantenuta volutamente una struttura analoga alle precedenti funzioni che usano +i semafori, anche se le due interfacce non possono essere completamente +equivalenti, specie per quanto riguarda la rimozione del mutex. La prima funzione (\texttt{\small 1-5}) è \func{CreateMutex}, e serve a creare il mutex; la funzione è estremamente semplice, e si limita @@ -3455,9 +3452,9 @@ mutex. La seconda funzione (\texttt{\small 6-10}) è \func{FindMutex}, che, come la precedente, è stata definita per mantenere una analogia con la corrispondente funzione basata sui semafori. Anch'essa si limita (\texttt{\small 9}) ad -aprire il file da usare per il \itindex{file~locking} \textit{file locking}, -solo che in questo caso le opzioni di \func{open} sono tali che il file in -questione deve esistere di già. +aprire il file da usare per il \textit{file locking}, solo che in questo caso +le opzioni di \func{open} sono tali che il file in questione deve esistere di +già. La terza funzione (\texttt{\small 11-22}) è \func{LockMutex} e serve per acquisire il mutex. La funzione definisce (\texttt{\small 14}) e inizializza @@ -3472,10 +3469,9 @@ La quarta funzione (\texttt{\small 24-34}) è \func{UnlockMutex} e serve a rilasciare il mutex. La funzione è analoga alla precedente, solo che in questo caso si inizializza (\texttt{\small 28-31}) la struttura \var{lock} per il rilascio del lock, che viene effettuato (\texttt{\small 33}) con la opportuna -chiamata a \func{fcntl}. Avendo usato il \itindex{file~locking} \textit{file - locking} in semantica POSIX (si riveda quanto detto -sez.~\ref{sec:file_posix_lock}) solo il processo che ha precedentemente -eseguito il lock può sbloccare il mutex. +chiamata a \func{fcntl}. Avendo usato il \textit{file locking} in semantica +POSIX (si riveda quanto detto sez.~\ref{sec:file_posix_lock}) solo il processo +che ha precedentemente eseguito il lock può sbloccare il mutex. La quinta funzione (\texttt{\small 36-39}) è \func{RemoveMutex} e serve a cancellare il mutex. Anche questa funzione è stata definita per mantenere una @@ -3513,11 +3509,13 @@ nessun inconveniente. \subsection{Il \textit{memory mapping} anonimo} \label{sec:ipc_mmap_anonymous} -\itindbeg{memory~mapping} Abbiamo già visto che quando i processi sono -\textsl{correlati}, se cioè hanno almeno un progenitore comune, l'uso delle -\textit{pipe} può costituire una valida alternativa alle code di messaggi; -nella stessa situazione si può evitare l'uso di una memoria condivisa facendo -ricorso al cosiddetto \textit{memory mapping} anonimo. +\itindbeg{memory~mapping} + +Abbiamo già visto che quando i processi sono \textsl{correlati}, se cioè hanno +almeno un progenitore comune, l'uso delle \textit{pipe} può costituire una +valida alternativa alle code di messaggi; nella stessa situazione si può +evitare l'uso di una memoria condivisa facendo ricorso al cosiddetto +\textit{memory mapping} anonimo. In sez.~\ref{sec:file_memory_map} abbiamo visto come sia possibile mappare il contenuto di un file nella memoria di un processo, e che, quando viene usato @@ -3543,6 +3541,7 @@ il \textit{memory mapping} anonimo.\footnote{nei sistemi derivati da SysV una 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} % TODO: fare esempio di mmap anonima @@ -3573,9 +3572,8 @@ una interfaccia completamente nuova, che tratteremo in questa sezione. Oggi Linux supporta tutti gli oggetti definito nello standard POSIX per l'IPC, ma a lungo non è stato così; la memoria condivisa è presente a partire dal kernel 2.4.x, i semafori sono forniti dalla \acr{glibc} nella sezione che -implementa i \itindex{thread} \textit{thread} POSIX di nuova generazione che -richiedono il kernel 2.6, le code di messaggi sono supportate a partire dal -kernel 2.6.6. +implementa i \textit{thread} POSIX di nuova generazione che richiedono il +kernel 2.6, le code di messaggi sono supportate a partire dal kernel 2.6.6. La caratteristica fondamentale dell'interfaccia POSIX è l'abbandono dell'uso degli identificatori e delle chiavi visti nel \textit{SysV-IPC}, per passare ai @@ -3784,16 +3782,16 @@ I suddetti limiti di sistema sono impostati attraverso altrettanti file in \texttt{/proc/sys/fs/mqueue}, in particolare i file che controllano i valori dei limiti sono: \begin{basedescript}{\desclabelwidth{1.5cm}\desclabelstyle{\nextlinelabel}} -\item[\sysctlfile{fs/mqueue/msg\_max}] Indica il valore massimo del numero di +\item[\sysctlfiled{fs/mqueue/msg\_max}] Indica il valore massimo del numero di messaggi in una coda e agisce come limite superiore per il valore di \var{attr->mq\_maxmsg} in \func{mq\_open}. Il suo valore di default è 10. Il - valore massimo è \const{HARD\_MAX} che vale \code{(131072/sizeof(void *))}, + valore massimo è \constd{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 \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 +\item[\sysctlfiled{fs/mqueue/msgsize\_max}] Indica il valore massimo della dimensione in byte di un messaggio sulla coda ed agisce come limite superiore per il valore di \var{attr->mq\_msgsize} in \func{mq\_open}. Il suo valore di default è 8192. Il valore massimo è 1048576 ed il valore @@ -3802,7 +3800,7 @@ dei limiti sono: 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 +\item[\sysctlfiled{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 @@ -3940,7 +3938,8 @@ I rispettivi prototipi sono: \fhead{time.h} \fdecl{int mq\_timedsend(mqd\_t mqdes, const char *msg\_ptr, size\_t msg\_len, \\ -\phantom{int mq\_timedsend(}unsigned int msg\_prio, const struct timespec *abs\_timeout)} +\phantom{int mq\_timedsend(}unsigned int msg\_prio, const struct timespec +*abs\_timeout)} \fdesc{Esegue l'inserimento di un messaggio su una coda entro un tempo specificato} } @@ -3975,7 +3974,7 @@ priorità maggiore vengono inseriti davanti a quelli di priorità inferiore, e quindi saranno riletti per primi. A parità del valore della priorità il messaggio sarà inserito in coda a tutti quelli che hanno la stessa priorità che quindi saranno letti con la politica di una \textit{fifo}. Il valore della -priorità non può eccedere il limite di sistema \const{MQ\_PRIO\_MAX}, che al +priorità non può eccedere il limite di sistema \constd{MQ\_PRIO\_MAX}, che al momento è pari a 32768. Qualora la coda sia piena, entrambe le funzioni si bloccano, a meno che non @@ -4196,7 +4195,7 @@ mount -t tmpfs -o size=128M,nr_inodes=10k,mode=700 tmpfs /mytmpfs Il filesystem riconosce, oltre quelle mostrate, le opzioni \texttt{uid} e \texttt{gid} che identificano rispettivamente utente e gruppo cui assegnarne la titolarità, e \texttt{nr\_blocks} che permette di specificarne la -dimensione in blocchi, cioè in multipli di \const{PAGECACHE\_SIZE} che in +dimensione in blocchi, cioè in multipli di \constd{PAGECACHE\_SIZE} che in questo caso è l'unità di allocazione elementare. La funzione che permette di aprire un segmento di memoria condivisa POSIX, ed @@ -4384,15 +4383,15 @@ restituendo al chiamante il valore di ritorno. \label{sec:ipc_posix_sem} Fino alla serie 2.4.x del kernel esisteva solo una implementazione parziale -dei semafori POSIX che li realizzava solo a livello di \itindex{thread} -\textit{thread} e non di processi,\footnote{questo significava che i semafori - erano visibili solo all'interno dei \itindex{thread} \textit{thread} creati - da un singolo processo, e non potevano essere usati come meccanismo di - sincronizzazione fra processi diversi.} fornita attraverso la sezione delle -estensioni \textit{real-time} della \acr{glibc} (quelle che si accedono -collegandosi alla libreria \texttt{librt}). Esisteva inoltre una libreria che -realizzava (parzialmente) l'interfaccia POSIX usando le funzioni dei semafori -di \textit{SysV-IPC} (mantenendo così tutti i problemi sottolineati in +dei semafori POSIX che li realizzava solo a livello di \textit{thread} e non +di processi,\footnote{questo significava che i semafori erano visibili solo + all'interno dei \textit{thread} creati da un singolo processo, e non + potevano essere usati come meccanismo di sincronizzazione fra processi + diversi.} fornita attraverso la sezione delle estensioni \textit{real-time} +della \acr{glibc} (quelle che si accedono collegandosi alla libreria +\texttt{librt}). Esisteva inoltre una libreria che realizzava (parzialmente) +l'interfaccia POSIX usando le funzioni dei semafori di \textit{SysV-IPC} +(mantenendo così tutti i problemi sottolineati in sez.~\ref{sec:ipc_sysv_sem}). A partire dal kernel 2.5.7 è stato introdotto un meccanismo di @@ -4426,7 +4425,7 @@ esistente o per crearne uno nuovi, i relativi prototipi sono: \fdesc{Crea un semaforo o ne apre uno esistente.} } {La funzione ritorna l'indirizzo del semaforo in caso di successo e - \const{SEM\_FAILED} per un errore, nel qual caso \var{errno} assumerà uno + \constd{SEM\_FAILED} per un errore, nel qual caso \var{errno} assumerà uno dei valori: \begin{errlist} \item[\errcode{EACCES}] il semaforo esiste ma non si hanno permessi @@ -4434,7 +4433,7 @@ esistente o per crearne uno nuovi, i relativi prototipi sono: \item[\errcode{EEXIST}] si sono specificati \const{O\_CREAT} e \const{O\_EXCL} ma il semaforo esiste. \item[\errcode{EINVAL}] il valore di \param{value} eccede - \const{SEM\_VALUE\_MAX} o il nome è solo ``\texttt{/}''. + \constd{SEM\_VALUE\_MAX} o il nome è solo ``\texttt{/}''. \item[\errcode{ENAMETOOLONG}] si è utilizzato un nome troppo lungo. \item[\errcode{ENOENT}] non si è usato \const{O\_CREAT} ed il nome specificato non esiste. @@ -4529,7 +4528,7 @@ semaforo con una chiamata a \func{sem\_post}) così che poi essa possa decrementarlo con successo e proseguire. Si tenga presente che la funzione può sempre essere interrotta da un segnale, -nel qual caso si avrà un errore di \const{EINTR}; inoltre questo avverrà +nel qual caso si avrà un errore di \errval{EINTR}; inoltre questo avverrà comunque, anche qualora si fosse richiesta la gestione con la semantica BSD, installando il gestore del suddetto segnale con l'opzione \const{SA\_RESTART} (vedi sez.~\ref{sec:sig_sigaction}) per riavviare le \textit{system call} @@ -4625,10 +4624,10 @@ prototipo è: La funzione incrementa di uno il valore corrente del semaforo indicato dall'argomento \param{sem}, se questo era nullo la relativa risorsa risulterà -sbloccata, cosicché un altro processo (o \itindex{thread} \textit{thread}) -eventualmente bloccato in una \func{sem\_wait} sul semaforo possa essere -svegliato e rimesso in esecuzione. Si tenga presente che la funzione è sicura -per l'uso all'interno di un gestore di segnali (si ricordi quanto detto in +sbloccata, cosicché un altro processo (o \textit{thread}) eventualmente +bloccato in una \func{sem\_wait} sul semaforo possa essere svegliato e rimesso +in esecuzione. Si tenga presente che la funzione è sicura per l'uso +all'interno di un gestore di segnali (si ricordi quanto detto in sez.~\ref{sec:sig_signal_handler}). Se invece di operare su un semaforo se ne volesse semplicemente leggere il @@ -4759,9 +4758,9 @@ prototipo è: La funzione inizializza un semaforo all'indirizzo puntato dall'argomento \param{sem}, e come per \func{sem\_open} consente di impostare un valore iniziale con \param{value}. L'argomento \param{pshared} serve ad indicare se -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). +il semaforo deve essere utilizzato dai \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 \textit{thread} di uno stesso processo (nel qual caso si parla di \textit{thread-shared semaphore}), @@ -4807,9 +4806,8 @@ La funzione prende come unico argomento l'indirizzo di un semaforo che deve essere stato inizializzato con \func{sem\_init}; non deve quindi essere applicata a semafori creati con \func{sem\_open}. Inoltre si deve essere sicuri che il semaforo sia effettivamente inutilizzato, la distruzione di un -semaforo su cui sono presenti processi (o \itindex{thread} \textit{thread}) in -attesa (cioè bloccati in una \func{sem\_wait}) provoca un comportamento -indefinito. +semaforo su cui sono presenti processi (o \textit{thread}) in attesa (cioè +bloccati in una \func{sem\_wait}) provoca un comportamento indefinito. Si tenga presente infine che utilizzare un semaforo che è stato distrutto con \func{sem\_destroy} di nuovo può dare esito a comportamenti indefiniti. Nel