Dopo il successo dell'esecuzione di una \func{fork} sia il processo padre che
il processo figlio continuano ad essere eseguiti normalmente a partire
-dall'istruzione successiva alla \func{fork}. Il processo figlio è una copia del
-padre, e riceve una copia dei \index{segmento!testo} segmenti di testo,
-\index{segmento!dati} dati e dello \itindex{stack} \textit{stack} (vedi
-sez.~\ref{sec:proc_mem_layout}), ed esegue esattamente lo stesso codice del
-padre. Si tenga presente però che la memoria è copiata e non condivisa,
-pertanto padre e figlio vedranno variabili diverse e le eventuali modifiche
-saranno totalmente indipendenti.
+dall'istruzione successiva alla \func{fork}. Il processo figlio è una copia
+del padre, e riceve una copia dei segmenti di testo, dati e dello
+\textit{stack} (vedi sez.~\ref{sec:proc_mem_layout}), ed esegue esattamente lo
+stesso codice del padre. Si tenga presente però che la memoria è copiata e non
+condivisa, pertanto padre e figlio vedranno variabili diverse e le eventuali
+modifiche saranno totalmente indipendenti.
Per quanto riguarda la gestione della memoria, in generale il
\index{segmento!testo} segmento di testo, che è identico per i due processi, è
\item gli identificatori per il controllo di sessione: il
\itindex{process~group} \textit{process group-ID} e il \textit{session id}
ed il terminale di controllo (vedi sez.~\ref{sec:sess_proc_group});
-\item la \index{directory~di~lavoro} directory di lavoro e la directory radice
- (vedi sez.~\ref{sec:file_work_dir} e sez.~\ref{sec:file_chroot});
+\item la directory di lavoro (vedi sez.~\ref{sec:file_work_dir}) e la
+ directory radice (vedi sez.~\ref{sec:file_chroot});
\item la maschera dei permessi di creazione dei file (vedi
sez.~\ref{sec:file_perm_management});
\item la maschera dei segnali bloccati (vedi
\item i segmenti di memoria condivisa agganciati al processo (vedi
sez.~\ref{sec:ipc_sysv_shm});
\item i limiti sulle risorse (vedi sez.~\ref{sec:sys_resource_limit});
-\item il valori di \textit{nice}, le priorità real-time e le affinità di
- processore (vedi sez.~\ref{sec:proc_sched_stand},
+\item il valori di \textit{nice}, le priorità \textit{real-time} e le affinità
+ di processore (vedi sez.~\ref{sec:proc_sched_stand},
sez.~\ref{sec:proc_real_time} e sez.~\ref{sec:proc_sched_multiprocess});
\item le variabili di ambiente (vedi sez.~\ref{sec:proc_environ}).
\item l'insieme dei descrittori associati alle code di messaggi POSIX (vedi
recuperato lo stato di terminazione di tutti quanti.
Al ritorno della funzione lo stato di terminazione del figlio viene salvato
-(come \itindex{value~result~argument} \textit{value result argument}) nella
-variabile puntata da \param{status} e tutte le risorse del kernel relative al
-processo (vedi sez.~\ref{sec:proc_termination}) vengono rilasciate. Nel caso
-un processo abbia più figli il valore di ritorno della funzione sarà impostato
-al \ids{PID} del processo di cui si è ricevuto lo stato di terminazione, cosa
-che permette di identificare qual è il figlio che è terminato.
+(come \textit{value result argument}) nella variabile puntata
+da \param{status} e tutte le risorse del kernel relative al processo (vedi
+sez.~\ref{sec:proc_termination}) vengono rilasciate. Nel caso un processo
+abbia più figli il valore di ritorno della funzione sarà impostato al
+\ids{PID} del processo di cui si è ricevuto lo stato di terminazione, cosa che
+permette di identificare qual è il figlio che è terminato.
\itindend{termination~status}
interessa memorizzare lo stato si può passare un puntatore nullo. Il valore
restituito da entrambe le funzioni dipende dall'implementazione, ma
tradizionalmente gli 8 bit meno significativi sono riservati per memorizzare
-lo \itindex{exit~status} stato di uscita del processo, e gli altri per
-indicare il segnale che ha causato la terminazione (in caso di conclusione
-anomala), uno per indicare se è stato generato un \textit{core dump} (vedi
-sez.~\ref{sec:sig_standard}), ecc.\footnote{le definizioni esatte si possono
- trovare in \file{<bits/waitstatus.h>} ma questo file non deve mai essere
- usato direttamente, esso viene incluso attraverso \file{<sys/wait.h>}.}
+lo stato di uscita del processo, e gli altri per indicare il segnale che ha
+causato la terminazione (in caso di conclusione anomala), uno per indicare se
+è stato generato un \textit{core dump} (vedi sez.~\ref{sec:sig_standard}),
+ecc.\footnote{le definizioni esatte si possono trovare in
+ \file{<bits/waitstatus.h>} ma questo file non deve mai essere usato
+ direttamente, esso viene incluso attraverso \file{<sys/wait.h>}.}
\begin{table}[!htb]
\centering
processo chiama una di queste funzioni esso viene completamente sostituito dal
nuovo programma, il \ids{PID} del processo non cambia, dato che non viene
creato un nuovo processo, la funzione semplicemente rimpiazza lo
-\itindex{stack} \textit{stack}, i \index{segmento!dati} dati ed il
-\index{segmento!testo} testo del processo corrente con un nuovo programma
-letto da disco, eseguendo il \itindex{link-loader} \textit{link-loader} con
-gli effetti illustrati in sez.~\ref{sec:proc_main}.
+\textit{stack}, i dati ed il testo del processo corrente con un nuovo
+programma letto da disco, eseguendo il \textit{link-loader} con gli effetti
+illustrati in sez.~\ref{sec:proc_main}.
Ci sono sei diverse versioni di \func{exec} (per questo la si è chiamata
famiglia di funzioni) che possono essere usate per questo compito, in realtà
(\ids{PPID});
\item l'\textsl{user-ID reale}, il \textsl{group-ID reale} ed i
\textsl{group-ID supplementari} (vedi sez.~\ref{sec:proc_access_id});
-\item la directory radice e la \index{directory~di~lavoro} directory di lavoro
- corrente (vedi sez.~\ref{sec:file_work_dir});
-\item la maschera di creazione dei file \itindex{umask} (\textit{umask}, vedi
+\item la directory radice (vedi sez.~\ref{sec:file_chroot}) e la directory di
+ lavoro corrente (vedi sez.~\ref{sec:file_work_dir});
+\item la maschera di creazione dei file (\textit{umask}, vedi
sez.~\ref{sec:file_perm_management}) ed i \textit{lock} sui file (vedi
sez.~\ref{sec:file_locking});
\item il valori di \textit{nice}, le priorità real-time e le affinità di
\item le mappature dei file in memoria (vedi sez.~\ref{sec:file_memory_map});
\item i segmenti di memoria condivisa SysV (vedi sez.~\ref{sec:ipc_sysv_shm})
e POSIX (vedi sez.~\ref{sec:ipc_posix_shm});
-\item i \itindex{memory~locking} \textit{memory lock} (vedi
- sez.~\ref{sec:proc_mem_lock});
+\item i \textit{memory lock} (vedi sez.~\ref{sec:proc_mem_lock});
\item le funzioni registrate all'uscita (vedi sez.~\ref{sec:proc_atexit});
\item i semafori e le code di messaggi POSIX (vedi
sez.~\ref{sec:ipc_posix_sem} e sez.~\ref{sec:ipc_posix_mq});
Anche queste funzioni sono un'estensione specifica di Linux, e non richiedono
nessun privilegio. I valori sono restituiti negli argomenti, che vanno
-specificati come puntatori (è un altro esempio di
-\itindex{value~result~argument} \textit{value result argument}). Si noti che
-queste funzioni sono le uniche in grado di leggere gli identificatori del
-gruppo \textit{saved}.
+specificati come puntatori (è un altro esempio di \textit{value result
+ argument}). Si noti che queste funzioni sono le uniche in grado di leggere
+gli identificatori del gruppo \textit{saved}.
Infine le funzioni \func{setfsuid} e \func{setfsgid} servono per impostare gli
identificatori del gruppo \textit{filesystem} che sono usati da Linux per il
l'argomento \param{user}. Ritorna poi nel vettore \param{groups} la lista dei
\ids{GID} dei gruppi a cui l'utente appartiene. Si noti che \param{ngroups},
che in ingresso deve indicare la dimensione di \param{group}, è passato come
-\itindex{value~result~argument} \textit{value result argument} perché, qualora
-il valore specificato sia troppo piccolo, la funzione ritorna $-1$, passando
-comunque indietro il numero dei gruppi trovati, in modo da poter ripetere la
-chiamata con un vettore di dimensioni adeguate.
+\textit{value result argument} perché, qualora il valore specificato sia
+troppo piccolo, la funzione ritorna $-1$, passando comunque indietro il numero
+dei gruppi trovati, in modo da poter ripetere la chiamata con un vettore di
+dimensioni adeguate.
Infine per impostare i gruppi supplementari di un processo ci sono due
funzioni, che possono essere usate solo se si hanno i privilegi di
\textit{real-time} (o nel caso di Adeos gestiti dalle code del nano-kernel),
in modo da poterli controllare direttamente qualora ci sia la necessità di
avere un processo con priorità più elevata di un \textit{interrupt
- handler}.} mentre con l'incorrere in un \itindex{page~fault} \textit{page
- fault} si possono avere ritardi non previsti. Se l'ultimo problema può
-essere aggirato attraverso l'uso delle funzioni di controllo della memoria
-virtuale (vedi sez.~\ref{sec:proc_mem_lock}), il primo non è superabile e può
-comportare ritardi non prevedibili riguardo ai tempi di esecuzione di
-qualunque processo.
+ handler}.} mentre con l'incorrere in un \textit{page fault} si possono
+avere ritardi non previsti. Se l'ultimo problema può essere aggirato
+attraverso l'uso delle funzioni di controllo della memoria virtuale (vedi
+sez.~\ref{sec:proc_mem_lock}), il primo non è superabile e può comportare
+ritardi non prevedibili riguardo ai tempi di esecuzione di qualunque processo.
Nonostante questo, ed in particolare con una serie di miglioramenti che sono
stati introdotti nello sviluppo del kernel,\footnote{in particolare a partire
maschera binaria: nei casi più comuni potrebbe bastare un intero a 32 bit, in
cui ogni bit corrisponde ad un processore, ma oggi esistono architetture in
cui questo numero può non essere sufficiente, e per questo è stato creato
-questo \index{tipo!opaco} tipo opaco e una interfaccia di gestione che
-permette di usare a basso livello un tipo di dato qualunque rendendosi
-indipendenti dal numero di bit e dalla loro disposizione. Per questo le
-funzioni richiedono anche che oltre all'insieme di processori si indichi anche
-la dimensione dello stesso con l'argomento \param{setsize}, per il quale, se
-non si usa l'allocazione dinamica che vedremo a breve, ed è in genere
-sufficiente passare il valore \code{sizeof(cpu\_set\_t)}.
+questo tipo opaco e una interfaccia di gestione che permette di usare a basso
+livello un tipo di dato qualunque rendendosi indipendenti dal numero di bit e
+dalla loro disposizione. Per questo le funzioni richiedono anche che oltre
+all'insieme di processori si indichi anche la dimensione dello stesso con
+l'argomento \param{setsize}, per il quale, se non si usa l'allocazione
+dinamica che vedremo a breve, ed è in genere sufficiente passare il valore
+\code{sizeof(cpu\_set\_t)}.
L'interfaccia di gestione degli insiemi di processori, oltre alla definizione
del tipo \type{cpu\_set\_t}, prevede una serie di macro di preprocessore per
lo stato corrente del flag che controlla la effettiva generazione dei
\textit{core dump}. Introdotta a partire dal kernel 2.3.20.
-\item[\const{PR\_SET\_ENDIAN}] Imposta la \itindex{endianness}
- \textit{endianness} del processo chiamante secondo il valore fornito
- in \param{arg2}. I valori possibili sono sono: \const{PR\_ENDIAN\_BIG}
- (\textit{big endian}), \const{PR\_ENDIAN\_LITTLE} (\textit{little endian}),
- e \const{PR\_ENDIAN\_PPC\_LITTLE} (lo pseudo \textit{little endian} del
+\item[\const{PR\_SET\_ENDIAN}] Imposta la \textit{endianness} del processo
+ chiamante secondo il valore fornito in \param{arg2}. I valori possibili sono
+ sono: \const{PR\_ENDIAN\_BIG} (\textit{big endian}),
+ \const{PR\_ENDIAN\_LITTLE} (\textit{little endian}), e
+ \const{PR\_ENDIAN\_PPC\_LITTLE} (lo pseudo \textit{little endian} del
PowerPC). Introdotta a partire dal kernel 2.6.18, solo per architettura
PowerPC.
-\item[\const{PR\_GET\_ENDIAN}] Ottiene il valore della \itindex{endianness}
- \textit{endianness} del processo chiamante, salvato sulla variabile puntata
- da \param{arg2} che deve essere passata come di tipo ``\ctyp{int
- *}''. Introdotta a partire dal kernel 2.6.18, solo su PowerPC.
+\item[\const{PR\_GET\_ENDIAN}] Ottiene il valore della \textit{endianness} del
+ processo chiamante, salvato sulla variabile puntata da \param{arg2} che deve
+ essere passata come di tipo ``\ctyp{int *}''. Introdotta a partire dal
+ kernel 2.6.18, solo su PowerPC.
\item[\const{PR\_SET\_FPEMU}] Imposta i bit di controllo per l'emulazione
della virgola mobile su architettura ia64, secondo il valore
La \textit{system call} richiede soltanto due argomenti: il
primo, \param{flags}, consente di controllare le modalità di creazione del
nuovo \textit{task}, il secondo, \param{child\_stack}, imposta l'indirizzo
-dello \itindex{stack} \textit{stack} per il nuovo \textit{task}, e deve essere
-indicato quando si intende creare un \textit{thread}. L'esecuzione del
-programma creato da \func{sys\_clone} riprende, come per \func{fork}, da
-dopo l'esecuzione della stessa.
-
-La necessità di avere uno \itindex{stack} \textit{stack} alternativo c'è solo
-quando si intende creare un \textit{thread}, in tal caso infatti il nuovo
-\textit{task} vede esattamente la stessa memoria del \textit{task}
+dello \textit{stack} per il nuovo \textit{task}, e deve essere indicato quando
+si intende creare un \textit{thread}. L'esecuzione del programma creato da
+\func{sys\_clone} riprende, come per \func{fork}, da dopo l'esecuzione della
+stessa.
+
+La necessità di avere uno \textit{stack} alternativo c'è solo quando si
+intende creare un \textit{thread}, in tal caso infatti il nuovo \textit{task}
+vede esattamente la stessa memoria del \textit{task}
``\textsl{padre}'',\footnote{in questo caso per padre si intende semplicemente
il \textit{task} che ha eseguito \func{sys\_clone} rispetto al \textit{task}
da essa creato, senza nessuna delle implicazioni che il concetto ha per i
illustreremo in dettaglio in sez.~\ref{sec:file_shared_access}.
\item[\const{CLONE\_FS}] se questo flag viene impostato il nuovo processo
- condividerà con il padre le informazioni
+ condividerà con il padre le informazioni relative all'albero dei file, ed in
+ particolare avrà la stessa radice (vedi sez.~\ref{sec:file_chroot}), la
+ stessa directory di lavoro (vedi sez.~\ref{sec:file_work_dir}) e la stessa
+ \textit{umask} (sez.~\ref{sec:file_perm_management}). Una modifica di una
+ qualunque di queste caratteristiche in un processo, avrà effetto anche
+ sull'altro. Se assente il nuovo processo riceverà una copia delle precedenti
+ informazioni, che saranno così indipendenti per i due processi.
\item[\const{CLONE\_IO}]
\item[\const{CLONE\_NEWIPC}]
file, o nell'accesso a meccanismi di intercomunicazione come la memoria
condivisa.
+\index{sezione~critica|(}
+
In questi casi, se non si dispone della possibilità di eseguire atomicamente
le operazioni necessarie, occorre che quelle parti di codice in cui si
-compiono le operazioni sulle risorse condivise (le cosiddette
-\index{sezione~critica} \textsl{sezioni critiche}) del programma, siano
-opportunamente protette da meccanismi di sincronizzazione (torneremo su queste
-problematiche di questo tipo in cap.~\ref{cha:IPC}).
+compiono le operazioni sulle risorse condivise, quelle che in genere vengono
+denominate ``\textsl{sezioni critiche}'' del programma, siano opportunamente
+protette da meccanismi di sincronizzazione (vedremo alcune problematiche di
+questo tipo in cap.~\ref{cha:IPC}).
+
+\index{sezione~critica|)}
Nel caso dei \textit{thread} invece la situazione è molto più delicata e
sostanzialmente qualunque accesso in memoria (a buffer, variabili o altro) può
di sincronizzazione che anche in questo caso sono disponibili (torneremo su
queste problematiche di questo tipo in cap.~\ref{sez:thread_xxx})
-\itindbeg{deadlock} Un caso particolare di \textit{race condition} sono poi i
-cosiddetti \textit{deadlock} (traducibile in \textsl{condizione di stallo}),
-che particolarmente gravi in quanto comportano spesso il blocco completo di un
+\itindbeg{deadlock}
+
+Un caso particolare di \textit{race condition} sono poi i cosiddetti
+\textit{deadlock} (traducibile in \textsl{condizione di stallo}), che
+particolarmente gravi in quanto comportano spesso il blocco completo di un
servizio, e non il fallimento di una singola operazione. Per definizione un
\textit{deadlock} è una situazione in cui due o più processi non sono più in
grado di proseguire perché ciascuno aspetta il risultato di una operazione che
Si dice \textsl{rientrante} una funzione che può essere interrotta in
qualunque punto della sua esecuzione ed essere chiamata una seconda volta da
-un altro \itindex{thread} \textit{thread} di esecuzione senza che questo
-comporti nessun problema nell'esecuzione della stessa. La problematica è
-comune nella programmazione \itindex{thread} \textit{multi-thread}, ma si
-hanno gli stessi problemi quando si vogliono chiamare delle funzioni
-all'interno dei gestori dei segnali.
+un altro \textit{thread} di esecuzione senza che questo comporti nessun
+problema nell'esecuzione della stessa. La problematica è comune nella
+programmazione \textit{multi-thread}, ma si hanno gli stessi problemi quando
+si vogliono chiamare delle funzioni all'interno dei gestori dei segnali.
Fintanto che una funzione opera soltanto con le variabili locali è rientrante;
-queste infatti vengono allocate nello \itindex{stack} \textit{stack}, ed
-un'altra invocazione non fa altro che allocarne un'altra copia. Una funzione
-può non essere rientrante quando opera su memoria che non è nello
-\itindex{stack} \textit{stack}. Ad esempio una funzione non è mai rientrante
-se usa una \index{variabili!globali} variabile globale o
-\index{variabili!statiche} statica.
+queste infatti vengono allocate nello \textit{stack}, ed un'altra invocazione
+non fa altro che allocarne un'altra copia. Una funzione può non essere
+rientrante quando opera su memoria che non è nello \textit{stack}. Ad esempio
+una funzione non è mai rientrante se usa una variabile globale o statica.
Nel caso invece la funzione operi su un oggetto allocato dinamicamente, la
cosa viene a dipendere da come avvengono le operazioni: se l'oggetto è creato
parte del programmatore.
In genere le funzioni di libreria non sono rientranti, molte di esse ad
-esempio utilizzano \index{variabili!statiche} variabili statiche, la
-\acr{glibc} però mette a disposizione due macro di compilatore,
-\macro{\_REENTRANT} e \macro{\_THREAD\_SAFE}, la cui definizione attiva le
-versioni rientranti di varie funzioni di libreria, che sono identificate
-aggiungendo il suffisso \code{\_r} al nome della versione normale.
+esempio utilizzano variabili statiche, la \acr{glibc} però mette a
+disposizione due macro di compilatore, \macro{\_REENTRANT} e
+\macro{\_THREAD\_SAFE}, la cui definizione attiva le versioni rientranti di
+varie funzioni di libreria, che sono identificate aggiungendo il suffisso
+\code{\_r} al nome della versione normale.
\index{funzioni!rientranti|)}