Codice rientrante: differenze tra le versioni

Contenuto cancellato Contenuto aggiunto
Kormoran (discussione | contributi)
Nessun oggetto della modifica
ValterVBot (discussione | contributi)
m Esempi: tag source deprecati, replaced: <source lang= → <syntaxhighlight lang= (2), </source> → </syntaxhighlight> (2)
 
(33 versioni intermedie di 29 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 una stessasingola copia del codice in memoria puòpossa essere condivisa ed eseguita contemporaneamente e senza risultati inaspettati da piùutenti multipli o [[processo (informatica)|processi]] separati. AffinchèLa unaprogrammazione procedura,rientrante routineè ovitale comunqueper unamolti partesistemi di[[multitasking]] codice(vedi sia rientrante deve soddisfare questi requisiti:[[thread-safe]]).
 
Affinché una routine o comunque una parte di codice sia rientrante deve soddisfare questi requisiti:
 
# Nessuna porzione del codice possa essere alterata durante l'esecuzione (codice ''non automodificante'');
# 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 non deve nè allocare nè deallocare aree di memoria, nè nello [[memoria heap|heap]] nè altrove (nel caso del C, '''non''' deve assolutamente usare nè ''malloc()'', nè ''free()'', nè le loro varianti; in Pascal non si devono usare nè ''new'', nè ''dispose'');
# Il codice deve usare, se necessarie, solo variabili temporanee allocate sullo stack.
# Il codice non deve modificare variabili globali 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 porreregolarne deil'accesso tramite [[semaforo (informatica)|semafori]] o delle [[sezione critica|sezioni critiche]] all'inizio di essa, 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.
La programmazione rientrante è vitale per molti sistemi [[multitasking]] (vedi [[thread-safe]]).
 
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]]