From 5eaf11a5e3e4daaee677554b68f4ba3c92c67b84 Mon Sep 17 00:00:00 2001 From: Simone Piccardi Date: Wed, 1 Jan 2003 13:40:42 +0000 Subject: [PATCH] Reindicizzati leak memory e race conditions --- fileadv.tex | 20 +++++++++++--------- filedir.tex | 3 ++- filestd.tex | 6 +++--- ipc.tex | 13 +++++++------ process.tex | 22 +++++++++++----------- prochand.tex | 38 +++++++++++++++++++------------------- session.tex | 3 ++- 7 files changed, 55 insertions(+), 50 deletions(-) diff --git a/fileadv.tex b/fileadv.tex index 78adf08..f29a8ef 100644 --- a/fileadv.tex +++ b/fileadv.tex @@ -313,12 +313,13 @@ della funzione. L'uso di \param{sigmask} è stato introdotto allo scopo di prevenire possibili race condition\footnote{in Linux però, non esistendo una system call apposita, la funzione è implementata nelle \acr{glibc} usando \func{select}, e la - possibilità di una race condition resta.} quando si deve eseguire un test su -una variabile assegnata da un gestore sulla base dell'occorrenza di un -segnale per decidere se lanciare \func{select}. Fra il test e l'esecuzione è -presente una finestra in cui potrebbe arrivare il segnale che non sarebbe -rilevato; la race condition diventa superabile disabilitando il segnale prima -del test e riabilitandolo poi grazie all'uso di \param{sigmask}. + possibilità di una race condition\index{race condition} resta.} quando si +deve eseguire un test su una variabile assegnata da un gestore sulla base +dell'occorrenza di un segnale per decidere se lanciare \func{select}. Fra il +test e l'esecuzione è presente una finestra in cui potrebbe arrivare il +segnale che non sarebbe rilevato; la race condition\index{race condition} +diventa superabile disabilitando il segnale prima del test e riabilitandolo +poi grazie all'uso di \param{sigmask}. @@ -1240,9 +1241,10 @@ processi scrivono, mescolando in maniera imprevedibile il loro output sul file. In tutti questi casi il \textit{file locking} è la tecnica che permette di -evitare le race condition, attraverso una serie di funzioni che permettono di -bloccare l'accesso al file da parte di altri processi, così da evitare le -sovrapposizioni, e garantire la atomicità delle operazioni di scrittura. +evitare le race condition\index{race condition}, attraverso una serie di +funzioni che permettono di bloccare l'accesso al file da parte di altri +processi, così da evitare le sovrapposizioni, e garantire la atomicità delle +operazioni di scrittura. diff --git a/filedir.tex b/filedir.tex index fed54e0..87913fe 100644 --- a/filedir.tex +++ b/filedir.tex @@ -1069,7 +1069,8 @@ sembri semplice, in realt prima vista. Infatti anche se sembrerebbe banale generare un nome a caso e creare il file dopo aver controllato che questo non esista, nel momento fra il controllo e la creazione si ha giusto lo spazio per una possibile \textit{race - condition} (si ricordi quanto visto in \secref{sec:proc_race_cond}). + condition}\index{race condition} (si ricordi quanto visto in +\secref{sec:proc_race_cond}). Le \acr{glibc} provvedono varie funzioni per generare nomi di file temporanei, di cui si abbia certezza di unicità (al momento della generazione); la prima diff --git a/filestd.tex b/filestd.tex index 78d67c2..eb62d0a 100644 --- a/filestd.tex +++ b/filestd.tex @@ -914,8 +914,8 @@ essere il seguente: ... nread = getline(&ptr, &n, file); \end{lstlisting} -e per evitare memory leak occorre ricordarsi di liberare \var{ptr} con -una \func{free}. +e per evitare memory leak\index{memory leak} occorre ricordarsi di liberare +\var{ptr} con una \func{free}. Il valore di ritorno della funzione indica il numero di caratteri letti dallo stream (quindi compreso il newline, ma non lo zero di @@ -1182,7 +1182,7 @@ restituito (si ricordi quanto detto in \secref{sec:proc_var_passing} a proposito dei \textit{value result argument}) l'indirizzo della stringa allocata automaticamente dalle funzioni. Occorre inoltre ricordarsi di invocare \func{free} per liberare detto puntatore quando la stringa non serve -più, onde evitare memory leak. +più, onde evitare memory leak\index{memory leak}. Infine una ulteriore estensione GNU definisce le due funzioni \func{dprintf} e \func{vdprintf}, che prendono un file descriptor al posto dello stream. Altre diff --git a/ipc.tex b/ipc.tex index 977f9f0..09ff74b 100644 --- a/ipc.tex +++ b/ipc.tex @@ -3026,12 +3026,13 @@ caratteristica della funzione \func{open} (illustrata in \secref{sec:file_open}) che prevede\footnote{questo è quanto dettato dallo standard POSIX.1, ciò non toglie che in alcune implementazioni questa tecnica possa non funzionare; in particolare per Linux, nel caso di NFS, si - è comunque soggetti alla possibilità di una race condition.} che essa -ritorni un errore quando usata con i flag di \const{O\_CREAT} e -\const{O\_EXCL}. In tal modo la creazione di un \textsl{file di lock} può -essere eseguita atomicamente, il processo che crea il file con successo si può -considerare come titolare del lock (e della risorsa ad esso associata) mentre -il rilascio si può eseguire con una chiamata ad \func{unlink}. + è comunque soggetti alla possibilità di una race + condition\index{race condition}.} che essa ritorni un errore quando usata +con i flag di \const{O\_CREAT} e \const{O\_EXCL}. In tal modo la creazione di +un \textsl{file di lock} può essere eseguita atomicamente, il processo che +crea il file con successo si può considerare come titolare del lock (e della +risorsa ad esso associata) mentre il rilascio si può eseguire con una chiamata +ad \func{unlink}. Un esempio dell'uso di questa funzione è mostrato dalle funzioni \func{LockFile} ed \func{UnlockFile} riportate in \figref{fig:ipc_file_lock} diff --git a/process.tex b/process.tex index c5f9187..1fbfc06 100644 --- a/process.tex +++ b/process.tex @@ -555,8 +555,8 @@ tollerante nei confronti di piccoli errori come quello di chiamate doppie a Il problema più comune e più difficile da risolvere che si incontra con le routine di allocazione è quando non viene opportunamente liberata la memoria -non più utilizzata, quello che in inglese viene chiamato \textit{memory-leak}, -cioè una \textsl{perdita di memoria}. +non più utilizzata, quello che in inglese viene chiamato \textit{memory + leak}\index{memory leak}, cioè una \textsl{perdita di memoria}. Un caso tipico che illustra il problema è quello in cui in una subroutine si alloca della memoria per uso locale senza liberarla prima di uscire. La @@ -569,7 +569,7 @@ Il problema momento, in corrispondenza ad una qualunque chiamata di \func{malloc}, che può essere in una sezione del codice che non ha alcuna relazione con la subroutine che contiene l'errore. Per questo motivo è sempre molto difficile trovare un -\textit{memory leak}. +\textit{memory leak}\index{memory leak}. In C e C++ il problema è particolarmente sentito. In C++, per mezzo della programmazione ad oggetti, il problema dei \textit{memory leak} è notevolmente @@ -615,10 +615,10 @@ molto complesse riguardo l'allocazione della memoria. \label{sec:proc_mem_alloca} Una possibile alternativa all'uso di \func{malloc}, che non soffre dei -problemi di \textit{memory leak} descritti in precedenza, è la funzione -\funcd{alloca}, che invece di allocare la memoria nello heap usa il segmento -di stack della funzione corrente. La sintassi è identica a quella di -\func{malloc}, il suo prototipo è: +problemi di \textit{memory leak}\index{memory leak} descritti in precedenza, è +la funzione \funcd{alloca}, che invece di allocare la memoria nello heap usa +il segmento di stack della funzione corrente. La sintassi è identica a quella +di \func{malloc}, il suo prototipo è: \begin{prototype}{stdlib.h}{void *alloca(size\_t size)} Alloca \param{size} byte nello stack. @@ -634,10 +634,10 @@ quindi non esiste un analogo della \func{free}) in quanto essa viene rilasciata automaticamente al ritorno della funzione. Come è evidente questa funzione ha molti vantaggi, anzitutto permette di -evitare alla radice i problemi di memory leak, dato che non serve più la -deallocazione esplicita; inoltre la deallocazione automatica funziona anche -quando si usa \func{longjmp} per uscire da una subroutine con un salto non -locale da una funzione (vedi \secref{sec:proc_longjmp}). +evitare alla radice i problemi di memory leak\index{memory leak}, dato che non +serve più la deallocazione esplicita; inoltre la deallocazione automatica +funziona anche quando si usa \func{longjmp} per uscire da una subroutine con +un salto non locale da una funzione (vedi \secref{sec:proc_longjmp}). Un altro vantaggio è che in Linux la funzione è molto più veloce di \func{malloc} e non viene sprecato spazio, infatti non è necessario gestire un diff --git a/prochand.tex b/prochand.tex index bddc07a..44dd0fc 100644 --- a/prochand.tex +++ b/prochand.tex @@ -2464,13 +2464,13 @@ condiviso, onde evitare problemi con le ottimizzazioni del codice. \textit{deadlock}\index{deadlock}} \label{sec:proc_race_cond} -Si definiscono \textit{race condition} tutte quelle situazioni in cui processi -diversi operano su una risorsa comune, ed in cui il risultato viene a -dipendere dall'ordine in cui essi effettuano le loro operazioni. Il caso -tipico è quello di un'operazione che viene eseguita da un processo in più -passi, e può essere compromessa dall'intervento di un altro processo che -accede alla stessa risorsa quando ancora non tutti i passi sono stati -completati. +Si definiscono \textit{race condition}\index{race condition} tutte quelle +situazioni in cui processi diversi operano su una risorsa comune, ed in cui il +risultato viene a dipendere dall'ordine in cui essi effettuano le loro +operazioni. Il caso tipico è quello di un'operazione che viene eseguita da un +processo in più passi, e può essere compromessa dall'intervento di un altro +processo che accede alla stessa risorsa quando ancora non tutti i passi sono +stati completati. Dato che in un sistema multitasking ogni processo può essere interrotto in qualunque momento per farne subentrare un'altro in esecuzione, niente può @@ -2483,22 +2483,22 @@ funzioner Per questo occorre essere ben consapevoli di queste problematiche, e del fatto che l'unico modo per evitarle è quello di riconoscerle come tali e prendere gli adeguati provvedimenti per far sì che non si verifichino. Casi tipici di -\textit{race condition} si hanno quando diversi processi accedono allo stesso -file, o nell'accesso a meccanismi di intercomunicazione come la memoria -condivisa. 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 +\textit{race condition}\index{race condition} si hanno quando diversi processi +accedono allo stesso file, o nell'accesso a meccanismi di intercomunicazione +come la memoria condivisa. 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 \textsl{sezioni critiche}\index{sezioni critiche}) del programma, siano opportunamente protette da meccanismi di sincronizzazione (torneremo su queste problematiche di questo tipo in \capref{cha:IPC}). -Un caso particolare di \textit{race condition} sono poi i cosiddetti -\textit{deadlock}\index{deadlock}, 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}\index{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 dovrebbe essere -eseguita dall'altro. +Un caso particolare di \textit{race condition}\index{race condition} sono poi +i cosiddetti \textit{deadlock}\index{deadlock}, 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}\index{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 dovrebbe essere eseguita dall'altro. L'esempio tipico di una situazione che può condurre ad un diff --git a/session.tex b/session.tex index 26df18c..45ca8e7 100644 --- a/session.tex +++ b/session.tex @@ -234,7 +234,8 @@ processo padre, per impostare il valore nel figlio, che da quest'ultimo, per sé stesso, in modo che il cambiamento di \textit{process group} sia immediato per entrambi; una delle due chiamate sarà ridondante, ma non potendo determinare quale dei due processi viene eseguito per primo, occorre eseguirle -comunque entrambe per evitare di esporsi ad una race condition. +comunque entrambe per evitare di esporsi ad una race +condition\index{race condition}. Si noti come nessuna delle funzioni esaminate finora permetta di spostare un processo da una sessione ad un altra; infatti l'unico modo di far cambiare -- 2.30.2