X-Git-Url: https://gapil.gnulinux.it/gitweb/?p=gapil.git;a=blobdiff_plain;f=prochand.tex;h=95df51da8b917df2af12cd4042c1f2e584b4467d;hp=2fd1924c82ecb8e777fe443a3039b244dfbaa0c7;hb=9b7af600ff0f73bc946c9d160c320667c7a91347;hpb=88d22f4971adcbdb816c405a1375ae0a8d57bdde diff --git a/prochand.tex b/prochand.tex index 2fd1924..95df51d 100644 --- a/prochand.tex +++ b/prochand.tex @@ -295,13 +295,12 @@ multitasking.\footnote{oggi questa rilevanza, con la diffusione dell'uso dei 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, è @@ -921,12 +920,12 @@ occorrerà continuare a chiamare la funzione più volte fintanto che non si è 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} @@ -1122,12 +1121,12 @@ terminazione del processo tramite il puntatore \param{status}, e se non 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{} ma questo file non deve mai essere - usato direttamente, esso viene incluso attraverso \file{}.} +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{} ma questo file non deve mai essere usato + direttamente, esso viene incluso attraverso \file{}.} \begin{table}[!htb] \centering @@ -1367,10 +1366,9 @@ fatto attraverso una delle funzioni della famiglia \func{exec}. Quando un 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à @@ -1539,9 +1537,9 @@ seguente: (\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 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 @@ -1575,8 +1573,7 @@ seguenti proprietà non vengano preservate: \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}); @@ -2100,10 +2097,9 @@ identificatori; i loro prototipi sono: 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 @@ -2209,10 +2205,10 @@ specificato per nome (e non con un \ids{UID}) nella stringa passata con 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 @@ -2681,12 +2677,11 @@ un processo qualsiasi sia la sua priorità,\footnote{questo a meno che non si \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 @@ -3186,13 +3181,13 @@ permette di identificare un insieme di processori. Il dato è normalmente una 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 @@ -3667,18 +3662,18 @@ momento:\footnote{alla stesura di questa sezione, cioè con il kernel 3.2.} 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 @@ -3979,14 +3974,14 @@ spazio separato dagli altri, che costituisce poi quello che viene chiamato un 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 @@ -4113,7 +4108,13 @@ elenco, che illustra quelle attualmente disponibili:\footnote{si fa 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}] @@ -4302,12 +4303,16 @@ gli adeguati provvedimenti per far sì che non si verifichino. Casi tipici di 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ò @@ -4317,9 +4322,11 @@ con estrema attenzione l'uso delle variabili ed utilizzare i vari meccanismi 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 @@ -4350,19 +4357,16 @@ eseguire in maniera atomica le operazioni necessarie. 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 @@ -4375,11 +4379,11 @@ se viene passato lo stesso oggetto; in tutti questi casi occorre molta cura da 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|)}