2011-08-31 15 views
8

Aquí está mi códigoPor qué la dirección de la variable de proceso hijo y el proceso primario es igual

int main() 
{ 
    pid_t pid; 
    int y = 3; 
    if ((pid = fork()) <0) 
    return -1;; 

    if(pid == 0) /* child */ 
    { 
    printf(" before: %d %p\n", y, &y); 
    y *= 10; 
    printf("after: %d %p\n", y, &y); 
    } 
    else /* father */ 
    { 
    sleep(1); 
    printf("father: %d %p\n" , y , &y); 

    } 
    return 0; 
} 

La salida del programa es como siguiente:

before: 3 ffbff440 
after: 30 ffbff440 
father: 3 ffbff440 

Mi pregunta es ¿por qué es la dirección del variable de niño y padre mismo, pero el valor diferente?

Respuesta

21

Porque es una dirección virtual, no física.

Cada proceso obtiene su propio espacio de direcciones (por ejemplo, un sistema de 32 bits puede permitir que cada proceso tenga su propio espacio de direcciones con el rango 4G completo).

Es la unidad de gestión de memoria que asignará las direcciones virtuales a las físicas (y manejará cosas como fallas de página si las páginas intercambiadas deben comprarse desde el almacenamiento secundario).

El siguiente diagrama puede ayudar, cada sección que representa un bloque de 4K de memoria:

Process A   Physical Memory  Process B 
    +-------+   +-------------+  +-------+ 
0K |  |----> 0K | (shared) | <----|  | 0K 
    +-------+   +-------------+  +-------+ 
4K |  |--+  4K |    | <----|  | 4K 
    +-------+ |  +-------------+  +-------+ 
8K |  | +-> 8K |    |  |  | 8K 
    +-------+   +-------------+  +-------+ 
     |    : : : : : : :   | 
     |    +-------------+   | 
     |   128K |    | <--------+ 
     |    +-------------+ 
     +--------> 132K |    | 
         +-------------+ 

se puede ver, en ese diagrama, la desconexión entre direcciones de memoria virtual y direcciones de memoria física (y la posibilidad de que procesos para compartir bloques de memoria también). Las direcciones en los lados izquierdo y derecho son direcciones virtuales que ven los procesos.

Las direcciones en el bloque central son direcciones físicas reales donde los datos son "realmente" y la MMU maneja la asignación. Para obtener una explicación más detallada de fork (y exec), también puede consultar this answer.

+0

También tenga en cuenta que tiene que ser así. Si la dirección de 'y' sí cambió, cualquier apuntador (dirección) retenido en variables o estructuras antes de la bifurcación ya no sería correcto después de la bifurcación. Eso haría que el fork sea mucho menos útil, ya que el proceso secundario no podría acceder a ninguna estructura de datos (listas vinculadas, árboles) o datos asignados dinámicamente desde antes, ya que esas cosas dependen de punteros. Los sistemas sin memoria virtual prácticamente no pueden implementar fork, en su lugar obtiene vfork (http://pubs.opengroup.org/onlinepubs/7908799/xsh/vfork.html). –

+0

No técnicamente "tiene que ser así": podría usar punteros doblemente indirectos siempre que su tiempo de ejecución de C sea compatible (en otras palabras, un puntero es un desplazamiento desde un valor conocido y, al bifurcar, mueve los datos a otro lugar para el niño y ajustar el valor conocido). Sin embargo, sería un asesino de rendimiento. Creo que Windows en modo real hizo algo similar a esto con el bloqueo y desbloqueo de la memoria. – paxdiablo

+1

Bastante justo, usted básicamente ha descrito una implementación de software barata y alegre (o costosa y miserable, según cómo la mire) de la memoria virtual. En ese caso, aún verá lo que observa el interrogador, que la dirección anterior y posterior a la horquilla se imprime con el mismo valor. A menos que el formateador de impresión '% p' también se haya agregado a la dirección base, supongo que :-) –

1

La dirección es la 'misma' ya que cada proceso tiene su propio espacio de direcciones virtuales y la variable generalmente se cargará en la misma ubicación. Tenga en cuenta que esta no es la dirección física en la memoria. También tenga en cuenta que hay esquemas que deliberadamente asignan al azar la ubicación en la que se carga un proceso para dificultar el ataque/pirateo del proceso. En ese caso, la dirección será diferente.

Cuestiones relacionadas