X-Git-Url: https://gapil.gnulinux.it/gitweb/?a=blobdiff_plain;f=prochand.tex;h=3522bbb2a2ae78f252a3516711b28ff3d41885ff;hb=47a00595786c34a03266f19dd5163a45da63e29f;hp=a6b8484628ed44335402b1bd7d0ce95b56dd9508;hpb=60e20d29c0515f95b8a171fb33c7214c9bf92021;p=gapil.git diff --git a/prochand.tex b/prochand.tex index a6b8484..3522bbb 100644 --- a/prochand.tex +++ b/prochand.tex @@ -155,7 +155,8 @@ periodico secondo la frequenza specificata dalla costante \const{HZ},\footnote{fino al kernel 2.4 il valore usuale di questa costante era 100, per tutte le architetture eccetto l'alpha, per la quale era 1000, nel 2.6 è stato portato a 1000 su tutte le architetture; occorre fare - attenzione a non confondere questo valore con quello dei clock tick (vedi + attenzione a non confondere questo valore con quello dei + \itindex{clock~tick} \textit{clock tick} (vedi sez.~\ref{sec:sys_unix_time}).} definita in \file{asm/param.h}, ed il cui valore è espresso in Hertz.\footnote{a partire dal kernel 2.6.21 è stato introdotto (a cura di Ingo Molnar) un meccanismo completamente diverso, @@ -193,9 +194,9 @@ abbastanza limitata sulle cause della terminazione del processo figlio. Quando un processo ha concluso il suo compito o ha incontrato un errore non risolvibile esso può essere terminato con la funzione \func{exit} (si veda quanto discusso in sez.~\ref{sec:proc_conclusion}). La vita del processo però -termina solo quando la notifica della sua conclusione viene ricevuta dal -processo padre, a quel punto tutte le risorse allocate nel sistema ad esso -associate vengono rilasciate. +termina completamente solo quando la notifica della sua conclusione viene +ricevuta dal processo padre, a quel punto tutte le risorse allocate nel +sistema ad esso associate vengono rilasciate. Avere due processi che eseguono esattamente lo stesso codice non è molto utile, normalmente si genera un secondo processo per affidargli l'esecuzione @@ -430,7 +431,6 @@ Se eseguiamo il comando\footnote{che senza specificare attese (come si può notare in (\texttt{\small 17--19}) i valori predefiniti specificano di non attendere), otterremo come output sul terminale: - \footnotesize \begin{verbatim} [piccardi@selidor sources]$ export LD_LIBRARY_PATH=./; ./forktest 3 @@ -451,17 +451,14 @@ Go to next child \normalsize Esaminiamo questo risultato: una prima conclusione che si può trarre è che non -si può dire quale processo fra il padre ed il figlio venga eseguito per -primo\footnote{a partire dal kernel 2.5.2-pre10 è stato introdotto il nuovo - \itindex{scheduler} \textit{scheduler} di Ingo Molnar che esegue sempre per - primo il figlio; per mantenere la portabilità è opportuno non fare comunque - affidamento su questo comportamento.} dopo la chiamata a \func{fork}; -dall'esempio si può notare infatti come nei primi due cicli sia stato eseguito -per primo il padre (con la stampa del \acr{pid} del nuovo processo) per poi -passare all'esecuzione del figlio (completata con i due avvisi di esecuzione -ed uscita), e tornare all'esecuzione del padre (con la stampa del passaggio al -ciclo successivo), mentre la terza volta è stato prima eseguito il figlio -(fino alla conclusione) e poi il padre. +si può dire quale processo fra il padre ed il figlio venga eseguito per primo +dopo la chiamata a \func{fork}; dall'esempio si può notare infatti come nei +primi due cicli sia stato eseguito per primo il padre (con la stampa del +\acr{pid} del nuovo processo) per poi passare all'esecuzione del figlio +(completata con i due avvisi di esecuzione ed uscita), e tornare +all'esecuzione del padre (con la stampa del passaggio al ciclo successivo), +mentre la terza volta è stato prima eseguito il figlio (fino alla conclusione) +e poi il padre. In generale l'ordine di esecuzione dipenderà, oltre che dall'algoritmo di \itindex{scheduler} scheduling usato dal kernel, dalla particolare situazione @@ -478,6 +475,24 @@ occorrer rischio di incorrere nelle cosiddette \itindex{race~condition} \textit{race condition} (vedi sez.~\ref{sec:proc_race_cond}). +In realtà a partire dal kernel 2.5.2-pre10 il nuovo \itindex{scheduler} +\textit{scheduler} di Ingo Molnar esegue sempre per primo il +figlio;\footnote{i risultati precedenti sono stati ottenuti su un kernel della + serie 2.4.} questa è una ottimizzazione che serve a evitare che il padre, +effettuando per primo una operazione di scrittura in memoria, attivi il +meccanismo del \itindex{copy~on~write} \textit{copy on write}. Questa +operazione infatti potrebbe risultare del tutto inutile qualora il figlio +fosse stato creato solo per eseguire una \func{exec}, in tal caso infatti si +invocherebbe un'altro proramma scartando completamente lo spazio degli +indirizzi, rendendo superflua la copia della memoria modificata dal padre. + +Eseguendo sempre per primo il figlio la \func{exec} verrebbe effettuata subito +avendo così la certezza che il \itindex{copy~on~write} \textit{copy on write} +viene utilizzato solo quando necessario. Quanto detto in precedenza vale +allora soltanto per i kernel fino al 2.4, per mantenere la portabilità è però +opportuno non fare affidamento su questo comportamento, che non si riscontra +in altri Unix e nelle versioni del kernel precendenti a quella indicata. + Si noti inoltre che essendo i segmenti di memoria utilizzati dai singoli processi completamente separati, le modifiche delle variabili nei processi figli (come l'incremento di \var{i} in \texttt{\small 31}) sono visibili solo @@ -489,7 +504,6 @@ Un secondo aspetto molto importante nella creazione dei processi figli quello dell'interazione dei vari processi con i file; per illustrarlo meglio proviamo a redirigere su un file l'output del nostro programma di test, quello che otterremo è: - \footnotesize \begin{verbatim} [piccardi@selidor sources]$ ./forktest 3 > output @@ -537,7 +551,7 @@ ogni figlio riceve una copia della memoria del padre, esso ricever quanto c'è nel buffer delle funzioni di I/O, comprese le linee scritte dal padre fino allora. Così quando il buffer viene scritto su disco all'uscita del figlio, troveremo nel file anche tutto quello che il processo padre aveva -scritto prima della sua creazione. E alla fine del file (dato che in questo +scritto prima della sua creazione. E alla fine del file (dato che in questo caso il padre esce per ultimo) troveremo anche l'output completo del padre. L'esempio ci mostra un altro aspetto fondamentale dell'interazione con i file, @@ -726,6 +740,8 @@ che sia cos terminato (si potrebbe avere cioè quello che si chiama un processo \textsl{orfano}). +% TODO verificare il reparenting + Questa complicazione viene superata facendo in modo che il processo orfano venga \textsl{adottato} da \cmd{init}. Come già accennato quando un processo termina, il kernel controlla se è il padre di altri processi in esecuzione: in @@ -735,7 +751,6 @@ avr cui riportare il suo stato di terminazione. Come verifica di questo comportamento possiamo eseguire il nostro programma \cmd{forktest} imponendo a ciascun processo figlio due secondi di attesa prima di uscire, il risultato è: - \footnotesize \begin{verbatim} [piccardi@selidor sources]$ ./forktest -c2 3 @@ -1186,15 +1201,15 @@ nuovo riceverne lo stato. \textbf{Macro} & \textbf{Descrizione}\\ \hline \hline - \const{WEXITED} & Ritorna quando un processo figlio è terminato. \\ + \const{WEXITED} & Ritorna quando un processo figlio è terminato.\\ \const{WNOHANG} & Ritorna immediatamente anche se non c'è niente da - notificare. \\ - \const{WSTOPPED} & Ritorna quando un processo figlio è stato fermato. \\ - \const{WCONTINUED}& ritorna quando un processo figlio che era stato - fermato ha ripreso l'esecuzione. \\ + notificare.\\ + \const{WSTOPPED} & Ritorna quando un processo figlio è stato fermato.\\ + \const{WCONTINUED}& Ritorna quando un processo figlio che era stato + fermato ha ripreso l'esecuzione.\\ \const{WNOWAIT} & Lascia il processo ancora in attesa di ricezione, così che una successiva chiamata possa di nuovo riceverne - lo stato. \\ + lo stato.\\ \hline \end{tabular} \caption{Costanti che identificano i bit dell'argomento \param{options} @@ -1226,7 +1241,8 @@ ritorno di \func{waitid} verranno avvalorati i seguenti campi: \const{CLD\_STOPPED}, \const{CLD\_CONTINUED} (vedi tab.~\ref{xxx_si_code}). \end{basedescript} -%TODO mettere riferimento alla tabella giusta +%TODO mettere riferimento alla tabella giusta (vedere man credentials e man +% waitid) Infine Linux, seguendo un'estensione di BSD, supporta altre due funzioni per la lettura dello stato di terminazione di un processo, analoghe alle @@ -1255,7 +1271,7 @@ utilizzata anche dalla funzione \func{getrusage} (vedi sez.~\ref{sec:sys_resource_use}) per ottenere le risorse di sistema usate da un processo; la sua definizione è riportata in fig.~\ref{fig:sys_rusage_struct}. -\subsection{Le funzioni \func{exec}} +\subsection{La funzione \func{exec} e le funzioni di esecuzione dei programmi} \label{sec:proc_exec} Abbiamo già detto che una delle modalità principali con cui si utilizzano i @@ -1471,8 +1487,8 @@ condivise, viene lanciato il \textit{linker} dinamico \cmd{/lib/ld.so} prima del programma per caricare le librerie necessarie ed effettuare il link dell'eseguibile. Se il programma è in formato ELF per caricare le librerie dinamiche viene usato l'interprete indicato nel segmento \const{PT\_INTERP}, -in genere questo è \file{/lib/ld-linux.so.1} per programmi collegati con le -\acr{libc5}, e \file{/lib/ld-linux.so.2} per programmi collegati con le +in genere questo è \sysfile{/lib/ld-linux.so.1} per programmi collegati con le +\acr{libc5}, e \sysfile{/lib/ld-linux.so.2} per programmi collegati con le \acr{glibc}. Infine nel caso il file sia uno script esso deve iniziare con una linea nella @@ -1488,7 +1504,7 @@ chiamato come se si fosse eseguito il comando \cmd{interpreter [argomenti] lunga restituisce un errore di \const{ENAMETOOLONG}, una comparazione dei vari comportamenti si trova su \href{http://www.in-ulm.de/~mascheck/various/shebang/} - {\texttt{http://www.in-ulm.de/\tild mascheck/various/shebang/}}.} + {\textsf{http://www.in-ulm.de/\tild mascheck/various/shebang/}}.} Con la famiglia delle \func{exec} si chiude il novero delle funzioni su cui è basata la gestione dei processi in Unix: con \func{fork} si crea un nuovo @@ -1516,16 +1532,18 @@ Come accennato in sez.~\ref{sec:intro_multiuser} il modello base\footnote{in realtà già esistono estensioni di questo modello base, che lo rendono più flessibile e controllabile, come le \itindex{capabilities} \textit{capabilities} illustrate in sez.~\ref{sec:proc_capabilities}, le ACL - per i file o il \itindex{Mandatory~Access~Control~(MAC)} \textit{Mandatory - Access Control} di SELinux; inoltre basandosi sul lavoro effettuato con + per i file (vedi sez.~\ref{sec:file_ACL}) o il + \itindex{Mandatory~Access~Control~(MAC)} \textit{Mandatory Access Control} + di \index{SELinux} SELinux; inoltre basandosi sul lavoro effettuato con SELinux, a partire dal kernel 2.5.x, è iniziato lo sviluppo di una - infrastruttura di sicurezza, il \textit{Linux Security Modules}, o LSM, in - grado di fornire diversi agganci a livello del kernel per modularizzare - tutti i possibili controlli di accesso.} di sicurezza di un sistema -unix-like è fondato sui concetti di utente e gruppo, e sulla separazione fra -l'amministratore (\textsl{root}, detto spesso anche \textit{superuser}) che -non è sottoposto a restrizioni, ed il resto degli utenti, per i quali invece -vengono effettuati i vari controlli di accesso. + infrastruttura di sicurezza, i \itindex{Linux~Security~Modules} + \textit{Linux Security Modules}, o LSM, in grado di fornire diversi agganci + a livello del kernel per modularizzare tutti i possibili controlli di + accesso.} di sicurezza di un sistema unix-like è fondato sui concetti di +utente e gruppo, e sulla separazione fra l'amministratore (\textsl{root}, +detto spesso anche \textit{superuser}) che non è sottoposto a restrizioni, ed +il resto degli utenti, per i quali invece vengono effettuati i vari controlli +di accesso. Abbiamo già accennato come il sistema associ ad ogni utente e gruppo due identificatori univoci, lo user-ID ed il group-ID; questi servono al kernel per @@ -1562,27 +1580,27 @@ tab.~\ref{tab:proc_uid_gid}. \hline \hline \acr{uid} & \textit{real} & \textsl{user-ID reale} - & indica l'utente che ha lanciato il programma\\ + & Indica l'utente che ha lanciato il programma.\\ \acr{gid} & '' &\textsl{group-ID reale} - & indica il gruppo principale dell'utente che ha lanciato - il programma \\ + & Indica il gruppo principale dell'utente che ha lanciato + il programma.\\ \hline \acr{euid} & \textit{effective} &\textsl{user-ID effettivo} - & indica l'utente usato nel controllo di accesso \\ + & Indica l'utente usato nel controllo di accesso.\\ \acr{egid} & '' & \textsl{group-ID effettivo} - & indica il gruppo usato nel controllo di accesso \\ + & Indica il gruppo usato nel controllo di accesso.\\ -- & -- & \textsl{group-ID supplementari} - & indicano gli ulteriori gruppi cui l'utente appartiene \\ + & Indicano gli ulteriori gruppi cui l'utente appartiene.\\ \hline -- & \textit{saved} & \textsl{user-ID salvato} - & è una copia dell'\acr{euid} iniziale\\ + & È una copia dell'\acr{euid} iniziale.\\ -- & '' & \textsl{group-ID salvato} - & è una copia dell'\acr{egid} iniziale \\ + & È una copia dell'\acr{egid} iniziale.\\ \hline \acr{fsuid} & \textit{filesystem} &\textsl{user-ID di filesystem} - & indica l'utente effettivo per l'accesso al filesystem \\ + & Indica l'utente effettivo per l'accesso al filesystem. \\ \acr{fsgid} & '' & \textsl{group-ID di filesystem} - & indica il gruppo effettivo per l'accesso al filesystem \\ + & Indica il gruppo effettivo per l'accesso al filesystem.\\ \hline \end{tabular} \caption{Identificatori di utente e gruppo associati a ciascun processo con @@ -1721,12 +1739,12 @@ il programma, effettuare il lavoro che non necessita di privilegi aggiuntivi, ed eventualmente tornare indietro. Come esempio per chiarire l'uso di queste funzioni prendiamo quello con cui -viene gestito l'accesso al file \file{/var/log/utmp}. In questo file viene +viene gestito l'accesso al file \sysfile{/var/log/utmp}. In questo file viene registrato chi sta usando il sistema al momento corrente; chiaramente non può essere lasciato aperto in scrittura a qualunque utente, che potrebbe falsificare la registrazione. Per questo motivo questo file (e l'analogo -\file{/var/log/wtmp} su cui vengono registrati login e logout) appartengono ad -un gruppo dedicato (\acr{utmp}) ed i programmi che devono accedervi (ad +\sysfile{/var/log/wtmp} su cui vengono registrati login e logout) appartengono +ad un gruppo dedicato (\acr{utmp}) ed i programmi che devono accedervi (ad esempio tutti i programmi di terminale in X, o il programma \cmd{screen} che crea terminali multipli su una console) appartengono a questo gruppo ed hanno il bit \acr{sgid} impostato. @@ -1740,8 +1758,8 @@ situazione degli identificatori \textsl{group-ID salvato} &=& \textrm{\acr{utmp}} \end{eqnarray*} in questo modo, dato che il \textsl{group-ID effettivo} è quello giusto, il -programma può accedere a \file{/var/log/utmp} in scrittura ed aggiornarlo. A -questo punto il programma può eseguire una \code{setgid(getgid())} per +programma può accedere a \sysfile{/var/log/utmp} in scrittura ed aggiornarlo. +A questo punto il programma può eseguire una \code{setgid(getgid())} per impostare il \textsl{group-ID effettivo} a quello dell'utente (e dato che il \textsl{group-ID reale} corrisponde la funzione avrà successo), in questo modo non sarà possibile lanciare dal terminale programmi che modificano detto file, @@ -1754,7 +1772,7 @@ in tal caso infatti la situazione degli identificatori sarebbe: \end{eqnarray*} e ogni processo lanciato dal terminale avrebbe comunque \acr{gid} come \textsl{group-ID effettivo}. All'uscita dal terminale, per poter di nuovo -aggiornare lo stato di \file{/var/log/utmp} il programma eseguirà una +aggiornare lo stato di \sysfile{/var/log/utmp} il programma eseguirà una \code{setgid(utmp)} (dove \var{utmp} è il valore numerico associato al gruppo \acr{utmp}, ottenuto ad esempio con una precedente \func{getegid}), dato che in questo caso il valore richiesto corrisponde al \textsl{group-ID salvato} la @@ -1765,7 +1783,7 @@ funzione avr \textsl{group-ID effettivo} &=& \textrm{\acr{utmp}} \\ \textsl{group-ID salvato} &=& \textrm{\acr{utmp} (invariato)} \end{eqnarray*} -consentendo l'accesso a \file{/var/log/utmp}. +consentendo l'accesso a \sysfile{/var/log/utmp}. Occorre però tenere conto che tutto questo non è possibile con un processo con i privilegi di amministratore, in tal caso infatti l'esecuzione di una @@ -2055,7 +2073,7 @@ un utente specifico, si pu \end{functions} La funzione esegue la scansione del database dei gruppi (usualmente -\file{/etc/groups}) cercando i gruppi di cui è membro l'utente \param{user} +\conffile{/etc/group}) cercando i gruppi di cui è membro l'utente \param{user} con cui costruisce una lista di gruppi supplementari, a cui aggiunge anche \param{group}, infine imposta questa lista per il processo corrente usando \func{setgroups}. Si tenga presente che sia \func{setgroups} che @@ -2109,12 +2127,12 @@ eseguibili,\footnote{una descrizione sommaria di questa funzionalit ma non essendo implementata non ne tratteremo qui.} in modo da poter stabilire quali capacità possono essere utilizzate quando viene messo in esecuzione uno specifico programma; attualmente però questa funzionalità non è -implementata.\footnote{per attualmente si intende fino al kernel 2.6.13, e - finora non è disponibile al momento neanche presente nessuna realizzazione - sperimentale delle specifiche POSIX.1e, anche se esistono dei patch di - sicurezza del kernel, come LIDS (vedi - \href{http://www.lids.org}{\texttt{http://www.lids.org/})} che realizzano - qualcosa di simile.} +implementata.\footnote{per attualmente si intende fino al kernel 2.6.23; + benché l'infrastruttura per crearla sia presente (vedi anche + sez.~\ref{sec:file_xattr}) finora non è disponibile nessuna realizzazione + delle specifiche POSIX.1e, esistono però dei patch di sicurezza del kernel, + come LIDS (vedi \href{http://www.lids.org}{\textsf{http://www.lids.org/})} + che realizzano qualcosa di simile.} \begin{table}[!h!bt] @@ -2195,7 +2213,8 @@ implementata.\footnote{per attualmente si intende fino al kernel 2.6.13, e (limitatamente a quelle che il processo chiamante ha nel suo insieme di capacità permesse) da qualunque processo.\\ - \const{CAP\_LINUX\_IMMUTABLE}& la capacità di impostare gli attributi +% TODO cambiata nel 2.4.24 rc1 ? + \const{CAP\_LINUX\_IMMUTABLE}& La capacità di impostare gli attributi \textit{immutable} e \itindex{append~mode} \textit{append only} per i file su un filesystem che supporta questi @@ -2206,7 +2225,7 @@ implementata.\footnote{per attualmente si intende fino al kernel 2.6.13, e \const{CAP\_NET\_BROADCAST}& La capacità di consentire l'uso di socket in \itindex{broadcast} \textit{broadcast} e \itindex{multicast} \textit{multicast}.\\ - \const{CAP\_NET\_ADMIN} & la capacità di eseguire alcune operazioni + \const{CAP\_NET\_ADMIN} & La capacità di eseguire alcune operazioni privilegiate sulla rete (impostare le opzioni privilegiate dei socket, abilitare il \itindex{multicast} \textit{multicasting}, @@ -2247,12 +2266,12 @@ implementata.\footnote{per attualmente si intende fino al kernel 2.6.13, e sistema.\\ \const{CAP\_SYS\_NICE} & La capacità di modificare le priorità dei processi (vedi sez.~\ref{sec:proc_priority}). \\ - \const{CAP\_SYS\_RESOURCE}& la capacità di superare le limitazioni sulle + \const{CAP\_SYS\_RESOURCE}& La capacità di superare le limitazioni sulle risorse, aumentare le quote disco, usare lo spazio disco riservato all'amministratore.\\ \const{CAP\_SYS\_TIME} & La capacità di modificare il tempo di sistema (vedi sez.~\ref{sec:sys_time}).\\ - \const{CAP\_SYS\_TTY\_CONFIG}& la capacità di simulare un \textit{hangup} + \const{CAP\_SYS\_TTY\_CONFIG}& La capacità di simulare un \textit{hangup} della console, con la funzione \func{vhangup}.\\ \const{CAP\_MKNOD} & La capacità di creare file di dispositivo con la @@ -2330,7 +2349,7 @@ un \textsl{AND} binario del contenuto corrente del \textit{capabilities capacità in esso elencate. Il \textit{capabilities bounding set} è un parametro di sistema, accessibile -attraverso il contenuto del file \file{/proc/sys/kernel/cap-bound}, che per +attraverso il contenuto del file \procfile{/proc/sys/kernel/cap-bound}, che per questa sua caratteristica consente di impostare un limite generale alle capacità che possono essere accordate ai vari processi. Questo valore può essere impostato ad un valore arbitrario esclusivamente dal primo processo @@ -3093,7 +3112,7 @@ tocca al kernel decidere quale deve essere eseguito. Il meccanismo con cui vengono gestiti questi processi dipende dalla politica di scheduling che si è scelta; lo standard ne prevede due: \begin{basedescript}{\desclabelwidth{1.2cm}\desclabelstyle{\nextlinelabel}} -\item[\textit{FIFO}] \textit{First In First Out}. Il processo viene eseguito +\item[\textsf{FIFO}] \textit{First In First Out}. Il processo viene eseguito fintanto che non cede volontariamente la CPU (con \func{sched\_yield}), si blocca, finisce o viene interrotto da un processo a priorità più alta. Se il processo viene interrotto da uno a priorità più alta esso resterà in cima @@ -3101,7 +3120,7 @@ scelta; lo standard ne prevede due: più alta diverranno inattivi. Se invece lo si blocca volontariamente sarà posto in coda alla lista (ed altri processi con la stessa priorità potranno essere eseguiti). -\item[\textit{RR}] \textit{Round Robin}. Il comportamento è del tutto analogo +\item[\textsf{RR}] \textit{Round Robin}. Il comportamento è del tutto analogo a quello precedente, con la sola differenza che ciascun processo viene eseguito al massimo per un certo periodo di tempo (la cosiddetta \textit{time slice}) dopo di che viene automaticamente posto in fondo alla @@ -3295,7 +3314,6 @@ dato che in Linux questo intervallo di tempo questa funzione ritorna sempre un valore di 150 millisecondi, e non importa specificare il PID di un processo reale. - Come accennato ogni processo che usa lo scheduling real-time può rilasciare volontariamente la CPU; questo viene fatto attraverso la funzione \funcd{sched\_yield}, il cui prototipo è: @@ -3315,8 +3333,12 @@ l'esecuzione non sar in modalità \textit{fifo}, per permettere l'esecuzione degli altri processi con pari priorità quando la sezione più urgente è finita. +% TODO: con il 2.6.23 il comportamento è stato leggermente modificato ed è +% stato introdotto /proc/sys/kernel/sched_compat_yield da mettere a 1 per aver +% la compatibilità con il precedente. -\subsection{Il controllo dello \textit{scheduler} per i sistemi multiprocessore} +\subsection{Il controllo dello \textit{scheduler} per i sistemi + multiprocessore} \label{sec:proc_sched_multiprocess} Infine con il supporto dei sistemi multiprocessore sono state introdotte delle @@ -3545,7 +3567,7 @@ qualunque momento, e le operazioni di un eventuale \textit{signal handler} sono compiute nello stesso spazio di indirizzi del processo. Per questo, anche il solo accesso o l'assegnazione di una variabile possono non essere più operazioni atomiche (torneremo su questi aspetti in -sez.~\ref{sec:sig_control}). +sez.~\ref{sec:sig_adv_control}). In questo caso il sistema provvede un tipo di dato, il \type{sig\_atomic\_t}, il cui accesso è assicurato essere atomico. In pratica comunque si può