Codice rientrante: differenze tra le versioni

Contenuto cancellato Contenuto aggiunto
Lornova (discussione | contributi)
Nuovo articolo, tradotto dalla wiki inglese
 
ValterVBot (discussione | contributi)
m Esempi: tag source deprecati, replaced: <source lang= → <syntaxhighlight lang= (2), </source> → </syntaxhighlight> (2)
 
(34 versioni intermedie di 30 utenti non mostrate)
Riga 1:
In [[informatica]], il codice di un [[Programma (informatica)|programma]] o di una [[subroutine|routine]] è detto '''rientrante''' se è progettato in modo che ununa singola copia del codice in memoria puòpossa essere condivisa ed eseguita contemporaneamente e senza risultati inaspettati da utenti multipli o [[processo (informatica)|processi]] separati. La chiave per progettare codiceprogrammazione rientrante è assicurarsivitale cheper nessunamolti porzionesistemi del[[multitasking]] codice(vedi possa essere alterata da un differente utente o processo, e che qualsiasi informazione specifica di un utente o processo sia mantenuta in un'area di memoria distinta[[thread-safe]]).
 
Affinché una routine o comunque una parte di codice sia rientrante deve soddisfare questi requisiti:
La programmazione rientrante è vitale per molti sistemi [[multitasking]] (vedi [[thread-safe]]).
 
# Nessuna porzione del codice possa essere alterata durante l'esecuzione (codice ''non automodificante'');
La parte di codice dei [[kernel]] che implementa la sincronizzazione interprocesso ([[semaforo (informatica)|semafori]], [[sezione critica|sezioni critiche]] ecc.) non è rientrante per definizione.
# Il codice non deve richiamare nessuna routine che non sia a sua volta rientrante. Per esempio molte implementazioni delle funzioni malloc() e free() in C non lo sono (stesso discorso per ''new'' e ''dispose'' in Pascal) e non devono essere utilizzate. In caso sia necessario allocare memoria si potrebbero utilizzare le API di sistema (dopo averne consultato la documentazione per avere la certezza che siano rientranti), che, potendo in teoria essere chiamate in qualsiasi momento e in qualsiasi situazione (perlomeno in un sistema pienamente multitasking) offrono maggiori garanzie.
# Il codice deve usare, se necessarie, solo variabili temporanee allocate sullo stack.
# Il codice non deve modificare né variabili globali né aree di memoria condivisa né impiegare variabili locali statiche.
 
Se una data porzione di codice non rispetta queste regole, non è possibile farla eseguire da più processi contemporaneamente ma è necessario regolarne l'accesso tramite [[semaforo (informatica)|semafori]] o [[sezione critica|sezioni critiche]], per assicurarsi che venga eseguita da un solo processo alla volta.
 
La parte di codice dei [[kernel]] che implementa la sincronizzazione interprocesso ([[semaforo (informatica)|semafori]], [[sezione critica|sezioni critiche]] ecc.) non è rientrante per definizione.
 
Il kernel dei sistemi operativi [[Windows NT]] è completamente rientrante, a differenza di quello di [[Windows 9x]], le cui notevoli porzioni di codice a [[16 bit]] derivate da [[MS-DOS]] non sono rientranti. Pertanto l'accesso a codice di sistema a 16 bit in Windows 9x è regolato da una sezione critica globale, con il risultato che spesso il sistema operativo opera in maniera ''monotask''.
 
Le [[funzione ricorsiva|funzioni ricorsive]] dovrebbero essere sempre rientranti, sebbene, con le dovute cautele, sia possibile scrivere funzioni ricorsive non rientranti.
== Esempi ==
Nel frammento di codice che segue, entrambe le funzioni <code>f()</code> e <code>g()</code> '''non''' sono rientranti.
 
<syntaxhighlight lang=c>
Nel frammento di codice che segue, entrambe le funzioni <code>f()</code> e <code>g()</code> non sono rientranti.
 
<pre>
int g_var = 1;
 
int f(){
{
g_var = g_var + 2;
return g_var;
}
 
int g(){
{
return f () + 2;
}
</syntaxhighlight>
</pre>
 
La funzione <code>f()</code> dipende dalla [[variabile globale]] <code>g_var</code>; perciò, se due processi eseguono la funzione ed accedono a <code>g_var</code> simultaneamente, il risultato dipende dalle tempistiche di esecuzioniesecuzione. Perciò, <code>f()</code> non è rientrante. Neppure <code>g()</code> è rientrante, perché richiama <code>f()</code> che non è rientrante.
 
Queste sono invece funzioni rientranti:
 
<syntaxhighlight lang=c>
int f(int i){
return i + 2;
}
 
int g(int i){
return f(i) + 2;
}
</syntaxhighlight>
 
== Collegamenti esterni ==
* Articolo "[http://www-106.ibm.com/developerworks/linux/library/l-reent.html Use reentrant functions for safer signal handling]" di [[Dipak K. Jha]] (in [[lingua inglese]]).
 
{{Portale|Informatica}}
[[Categoria:Programmazione]]
 
[[en:Reentrant]]
[[Categoria:Programmazione concorrente]]
[[de:Eintrittsinvarianz]]