2010-02-16 19 views
25

¿Podría alguien decirme qué código se puede llamar código de "reentrada"?¿Qué tipo de código se puede llamar "reentrante"?

me encontré con esta palabra cuando la lectura de algún sistema operativo en tiempo real. ¿Qué disciplinas se deben pegar para que el código sea código de "reentrada"?

+3

es curiosamente el primer hit de google: http://en.wikipedia.org/wiki/Reentrant_(subroutine) –

+0

@Mitch, y si alguien extrae el bit que es relevante para RTOS lo vuelve a etiquetar y lo vuelve específico para las "disciplinas" eso debe ser pegado a "un poco de la pregunta, entonces con un poco de suerte, el primer hit de Google se convertirá en esta pregunta y, por lo tanto, TAN ... que todos queremos, ¿no? =) – Rob

+0

@Rob: tal vez. Es difícil decir ..... –

Respuesta

41

En general, un reentrante bloque de código es uno que se puede introducir por otro actor antes de una invocación anterior ha terminado, sin afectar a la ruta que el primer actor habría tomado a través del código. Es decir, es posible volver a ingresar el código mientras se está ejecutando y seguir produciendo resultados correctos.

En la mayoría de los casos, los "actores" son hilos de un mismo proceso, pero los conceptos de thread safety y re-entrante son sutilmente diferentes: no todos los bloques de hilos de seguridad se re-entrante, pero cada reentrante bloque es seguro para subprocesos. Es decir, la reincorporación es una propiedad más sólida que la seguridad de subprocesos. Aquí está a good example de Raymond Chen de cómo un bloque de código puede ser seguro para subprocesos pero no reentrante.

Hay un caso especial cuando el código es recursivo: el mismo actor está poniendo en el código antes de finalizar su propia invocación, como señala Marc Gravell. Todos los bloques recursivos correctos son reentrantes; por supuesto, no todos los bloques reentrantes son recursivos.

+0

gracias por todas las respuestas, sin embargo , solo puedo marcar 1 respuesta como la respuesta. lo siento por eso..: D – smwikipedia

+1

No todos los bloques recursivos son re-entrantes. En algunos compiladores 8x51, las variables locales se almacenan en direcciones estáticas. Las rutinas que se pueden llamar recursivamente tienen una bandera "en uso"; si la rutina entra cuando se establece el indicador "en uso", que copiará sus variables a una pila y borrar el indicador. Antes de que la rutina realice una llamada que podría repetirse, establece la bandera "en uso"; una vez que la llamada retorna, si la bandera no está configurada, la rutina vuelve a cargar sus variables fuera de la pila. Las rutinas codificadas de esta manera respaldan la recursión, pero no son reentrantes. – supercat

+2

_ "... pero cada bloque entrante es seguro para subprocesos." _ ¿Le importaría echar un vistazo a la [entrada de Wikipedia sobre reentrada] (http://en.wikipedia.org/wiki/Reentrancy_%28computing% 29)? Porque hay un ejemplo de una función que es reentrante pero no es segura. ¿Es posible que el editor haya cometido un error ?. Gracias. –

1

Puede otro hilo de llamar al código mientras que un primer hilo se encuentra en medio de ejecutarlo? Si el código cede a una función de devolución de llamada, ¿puede la función de devolución de llamada llamar al código antes de que se complete el primer recorrido?

Si el código utiliza VARs globales que no están bloqueados, o tiene su propia estática vars que no toma precauciones especiales con, cualquiera de esos escenarios podría romperlo.

9

Prácticamente cualquier tipo de código recursivo podrían ser clasificados como de reentrada (es decir, se puede llamar de nuevo en el mismo método sin haber terminado), pero esto se utiliza en particular cuando se habla de cerraduras, mutex, semáforos, etc. Para ejemplo, un bloqueo es reentrante si una vez que tenga el bloqueo puede éxito "bloquear" el código de nuevo (es decir, no a sí mismo callejón sin salida) - por ejemplo:

public void AddIfNecessary(string s) { 
    lock(syncObj) { 
     if(!Contains(s)) Add(s); 
    } 
} 

public void Add(string s) { 
    lock(syncObj) { 
     list.Add(s); 
    } 
} 

public bool Contains(string s) { 
    lock(syncObj) { 
     return list.Contains(s); 
    } 
} 

Aquí el hecho de que la el bloqueo es reentrante significa que podemos llamar al Contains y Add sin preocuparnos de que ya tengamos el "ex clusive "lock, simplificando el código. Internamente, se utiliza un contador en lugar de una simple bandera "en uso". La respuesta de

10

John Feminella dice:

un reentrante bloque de código es el que se pueden introducir por otro actor antes una invocación anterior ha terminado. Es decir, es posible volver a ingresar el código mientras ya se está ejecutando.

Pero eso también es cierto para un bloque de código no reentrante. Si el bloque de código se ha escrito sin tener en cuenta este problema, aún será posible que un segundo actor lo introduzca simultáneamente.

La cuestión es el efecto que esto tiene sobre los resultados de cualquiera de invocación.Entonces, con mayor precisión: un bloque reentrante es aquel que puede ser ingresado por otro actor antes de que una invocación anterior haya finalizado, sin cambiar el resultado de cualquiera de las dos invocación.

Ninguna invocación debería ser capaz de detectar la "presencia" de la otra.

+2

No me di cuenta que esta respuesta hasta ahora mismo! Gracias por la aclaración; tienes razón de que podría haber sido más específico. Voy a enmendar en consecuencia. –

0

Un programa de computadora se llama reentrante si se puede interrumpir en el medio de su ejecución y luego se vuelve a llamar de manera segura antes de que se completen las ejecuciones previas. La interrupción podría ser causada por una acción interna, como un salto o una llamada, o por una acción externa, como una interrupción o señal de hardware. Una vez que la invocación reingresada se completa, las invocaciones anteriores reanudarán la ejecución correcta.

+0

¿Agregar referencia a Wikipedia? http://en.wikipedia.org/wiki/Reentrant_(subroutine) – greeness

3

El código de reentrada es cuando las páginas comparten un recurso común y el recurso no se debe cambiar ni manipular. Entonces este recurso se conoce como código reentrante o código puro.

1

Código que puede invocarse mediante diferentes subprocesos que se ejecutan en paralelo. Por lo tanto, el código:

  1. puede tener variables locales (asignado en la pila de cada hilo)
  2. debe tener variables globales y estáticas vigilados, ya que las roscas estarán compartiendo ellos y habrá una carrera condición aquí.
0

ejemplo no reentrante

class Test { 
    int count; 

    // Here method1() is not reentrant 
    int method1() 
    { 
     return count + 1; 
    } 
} 

ejemplo Reentrante

class Test { 
    int count; 

    // Here method1() is reentrant 
    int method1(int count) 
    { 
     return count + 1; 
    } 
} 
0

simplemente decir, un código reentrante es un código que puede ser compartido entre múltiples procesos.

Esto es posible cuando se cumplan las siguientes condiciones:

  1. No debe tener datos globales y estáticos.
  2. No debería modificar su propio código.
  3. No debe llamar a otra función de reentrada o segmento de código.

Por lo tanto, un código que sigue estas condiciones se puede llamar código de reentrantes.

+0

Creo que esto no es realmente correcto. Las rutinas en objetos compartidos satisfacen las condiciones 2ª y 3ª, pero tienen datos globales y estáticos y son reentrantes en función de su definición porque se comparten entre muchos procesos. –

Cuestiones relacionadas