\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
\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
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}.
\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}
+