X-Git-Url: https://gapil.gnulinux.it/gitweb/?p=gapil.git;a=blobdiff_plain;f=ipc.tex;h=a7cb5768702723fc39aeafb1b03b17e5da4ae6ca;hp=6ecd5b161ddb4e9888c93d8b49a4885e941dd77e;hb=6725bff66b54efcaa3c054d0424721f0adb6396f;hpb=e7c1eaebbc012ee182a8d82fc75968969549821d diff --git a/ipc.tex b/ipc.tex index 6ecd5b1..a7cb576 100644 --- a/ipc.tex +++ b/ipc.tex @@ -1314,8 +1314,10 @@ invece: \item i campi \var{msg\_stime} e \var{msg\_rtime}, che esprimono rispettivamente il tempo in cui è stato inviato o ricevuto l'ultimo messaggio sulla coda, sono inizializzati a 0. -\item il campo \var{msg\_ctime} viene inizializzato al tempo corrente. -\item il campo \var{msg\_qbytes} viene inizializzato al valore preimpostato +\item il campo \var{msg\_ctime}, che esprime il tempo di creazione della coda, + viene inizializzato al tempo corrente. +\item il campo \var{msg\_qbytes} che esprime la dimensione massima del + contenuto della coda (in byte) viene inizializzato al valore preimpostato del sistema (\macro{MSGMNB}). \item i campi \var{msg\_first} e \var{msg\_last} che esprimono l'indirizzo del primo e ultimo messaggio sono inizializzati a \macro{NULL} e @@ -1342,7 +1344,7 @@ prototipo \begin{errlist} \item[\macro{EACCES}] Si è richiesto \macro{IPC\_STAT} ma processo chiamante non ha i privilegi di lettura sulla coda. - \item[\macro{EIDRM}] La coda richiesta è marcata per essere cancellata. + \item[\macro{EIDRM}] La coda richiesta è stata cancellata. \item[\macro{EPERM}] Si è richiesto \macro{IPC\_SET} o \macro{IPC\_RMID} ma il processo non ha i privilegi, o si è richiesto di aumentare il valore di \var{msg\_qbytes} oltre il limite \macro{MSGMNB} senza essere @@ -1615,8 +1617,9 @@ A ciascun insieme di semafori riportata in \figref{fig:ipc_semid_sd}, come nel caso delle code di messaggi quando si crea un nuovo insieme di semafori con \func{semget} questa struttura viene inizializzata, in particolare il campo \var{sem\_perm} viene -inizializzato come illustrato in \secref{sec:ipc_sysv_access_control}, per -quanto riguarda gli altri campi invece: +inizializzato come illustrato in \secref{sec:ipc_sysv_access_control} (si +ricordi che in questo caso il permesso di scrittura è in realtà permesso di +alterare il semaforo), per quanto riguarda gli altri campi invece: \begin{itemize*} \item il campo \var{sem\_nsems}, che esprime il numero di semafori nell'insieme, viene inizializzato al valore di \param{nsems}. @@ -1645,24 +1648,146 @@ struct semid_ds \label{fig:ipc_semid_sd} \end{figure} +Come per le code di messaggi anche per gli insiemi di semafori esistono una +serie di limiti, i cui valori sono associati ad altrettante costanti, che si +sono riportate in \tabref{tab:ipc_sem_limits}. Alcuni di questi sono +accessibili e modificabili al solito attraverso \func{sysctl} o scrivendo +direttamente nel file \file{/proc/sys/kernel/sem}. + \begin{table}[htb] \footnotesize \centering - \begin{tabular}[c]{|c|r|l|l|} + \begin{tabular}[c]{|c|r|p{8cm}|} \hline \textbf{Costante} & \textbf{Valore} & \textbf{Significato} \\ \hline \hline - \macro{SEMMNI}& 16& Numero massimo di insiemi di semafori. \\ - \macro{SEMMAX}& 8192& .\\ - \macro{SEMMNB}&16384& .\\ + \macro{SEMMNI}& 128 & Numero massimo di insiemi di semafori. \\ + \macro{SEMMSL}& 250 & Numero massimo di semafori per insieme.\\ + \macro{SEMMNS}&\macro{SEMMNI}*\macro{SEMMSL}& Numero massimo di semafori + nel sistema .\\ + \macro{SEMVMX}& 32767 & Massimo valore per un semaforo.\\ + \macro{SEMOPM}& 32 & Massimo numero di operazioni per chiamata a + \func{semop}. \\ + \macro{SEMMNU}&\macro{SEMMNS}& Massimo numero di strutture di ripristino.\\ + \macro{SEMUME}&\macro{SEMOPM}& Massimo numero di voci di ripristino.\\ + \macro{SEMAEM}&\macro{SEMVMX}& valore massimo per l'aggiustamento + all'uscita. \\ \hline \end{tabular} \caption{Valori delle costanti associate ai limiti degli insiemi di - semafori.} + semafori, definite in \file{linux/sem.h}.} \label{tab:ipc_sem_limits} \end{table} +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{sezioni critiche} del +codice (si ricordi quanto detto in \secref{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 +del codice. In questo modo l'accesso ad una risorsa condivisa da più processi +può essere controllato, associando ad essa un semaforo che consente di +assicurare che non più di un processo alla volta possa usarla. + +Il concetto di semaforo è uno dei concetti base nella programmazione ed è +assolutamente generico, così come del tutto generali sono modalità con cui lo +si utilizza. Un processo che deve accedere ad una risorsa eseguirà un +controllo del semaforo: se questo è positivo il suo valore sarà decrementato, +indicando che si è consumato una unità della risorsa, ed il processo potrà +proseguire nell'utilizzo di quest'ultima, provvedendo a rilasciarla, una volta +completate le operazioni volute, reincrementando il semaforo. + +Se al momento del controllo il valore del semaforo è nullo, siamo invece in +una situazione in cui la risorsa non è disponibile, ed il processo si +bloccherà in stato di \textit{sleep} fin quando chi la sta utilizzando non la +rilascerà, incrementando il valore del semaforo. Non appena il semaforo torna +positivo, indicando che la risorsa è disponibile, il processo sarà svegliato, +e si potrà operare come nel caso precedente (decremento del semaforo, accesso +alla risorsa, incremento del semaforo). + +Per poter implementare questo tipo di logica le operazioni di controllo e +decremento del contatore associato al semaforo devono essere atomiche, +pertanto una realizzazione di un oggetto di questo tipo è necessariamente +demandata al kernel. La forma più semplice di semaforo è quella del +\textsl{semaforo binaria}, o \textit{mutex}, in cui un valore diverso da zero +(normalmente 1) indica la libertà di accesso, e un valore nullo l'occupazione +della risorsa; in generale però si possono usare semafori con valori interi, +utilizzando il valore del contatore come indicatore del ``numero di risorse'' +ancora disponibili. + +Purtroppo l'implementazione effettuata nel sistema di intercomunicazione di +System V complica inutilmente questo schema elementare: anzittutto non è +possibile definire un singolo semaforo, ma se ne deve creare per forza un +insieme, specificando il numero di semafori che esso deve contenere con +l'argomento \param{nsem} di \func{semget}. + +Ma i difetti maggiori dei semafori nel System V IPC sono due: il primo è che +non esiste una funzione che permetta di creare ed inizializzare un semaforo in +un'unica operazione atomica; occorre prima creare l'insieme con \func{semget} +e poi inizializzarlo con \func{semctl}. + +Il secondo è che essendo i semafori delle risorse globali di sistema, che non +vengono cancellate quando nessuno le usa più, ci si trova a dover affrontare +esplicitamente il caso in cui un processo termina per un qualche errore, +lasciando un semaforo occupato, che resterà tale per sempre, a meno di non +rimediare la situazione con opportune operazioni di ripristino. + +Come accennato una volta creato l'insieme di semafori per l'inizializzazione +dei valori occorre ricorrere ad una funzione separata, \func{semctl}, che è +quella che effettua le operazioni di controllo; il suo prototipo è: +\begin{functions} + \headdecl{sys/types.h} + \headdecl{sys/ipc.h} + \headdecl{sys/sem.h} + + \funcdecl{int semctl(int semid, int semnum, int cmd, ...)} + + Esegue le operazioni di controllo su un semaforo o un insieme di semafori. + + \bodydesc{La funzione restituisce 0 in caso di successo o -1 in caso di + errore, nel qual caso \var{errno} viene settato a: + \begin{errlist} + \item[\macro{EACCES}] Il processo non ha i privilegi per eseguire + l'operazione richiesta. + \item[\macro{EIDRM}] L'insieme di semafori è stato cancellato. + \item[\macro{EPERM}] Si è richiesto \macro{IPC\_SET} o \macro{IPC\_RMID} ma + il processo non ha privilegi sufficienti ad eseguire l'operazione. + \item[\macro{ERANGE}] Si è richiesto \macro{SETALL} \macro{SETVAL} ma il + valore a cui si vuole impostare il semaforo è minore di zero o maggiore + di \macro{SEMVMX}. + \end{errlist} + ed inoltre \macro{EFAULT} ed \macro{EINVAL}. +} +\end{functions} + +La funzione può avere tre o quattro parametri, a seconda dell'operazione +specificata con \param{cmd} + + + + + +\begin{figure}[!htb] + \footnotesize \centering + \begin{minipage}[c]{15cm} + \begin{lstlisting}[labelstep=0]{} +struct sembuf +{ + unsigned short int sem_num; /* semaphore number */ + short int sem_op; /* semaphore operation */ + short int sem_flg; /* operation flag */ +}; + \end{lstlisting} + \end{minipage} + \normalsize + \caption{La struttura \var{sembuf}, usata per le operazioni sui + semafori.} + \label{fig:ipc_sembuf} +\end{figure} +