2012-03-15 10 views
5

soy nuevo en "fork()", leo en todas partes que cuando se llama fork() se inicia una copia exacta del proceso actual (de llamada). Ahora cuando ejecuto el siguiente código, debe haber dos procesos diferentes, teniendo dos ubicaciones de memoria diferentes asignadas a sus vars y funciones.¿Cómo se mapea la memoria cuando se usa la horquilla?

#include<stdio.h> 
int i=10; 
int pid; 
int main(){ 
    if((pid=fork())==0){ 
    i++;//somewhere I read that separate memory space for child is created when write is needed 
    printf("parent address= %p\n",&i);// this should return the address from parent's memory space 
    }else{ 
    i++; 
    i++; 
    printf("child address= %p\n",&i);// this should return the address of child's memory space 
    } 
    wait(0); 
    return(0); 
} 
 
Why The output looks like:: 
child address::804a01c 
parent address::804a01c 

Por qué tanto la dirección son los mismos para los padres, así como los niños?

+4

Ellos * tenían mejor * ser lo mismo. Desea que los punteros hagan referencia a la memoria de la misma manera en ambos procesos (incluso si ambos fragmentos de memoria son distintos). Lea sobre * memoria virtual *, esto responderá a su pregunta. –

+1

Tenga en cuenta que los * valores * de 'i' son diferentes entre padre e hijo, aunque ambas copias se almacenan en la misma dirección virtual. – markgz

Respuesta

8

teniendo dos ubicaciones de memoria diferentes asignadas a sus vars y funciones.

Nope; Linux implementa virtual memory, lo que significa que cada proceso tiene su propio espacio de direcciones completo. Como resultado, después de fork, ambos procesos ven las mismas direcciones para sus copias de objetos en memoria.

:

+4

El "lado" es de hecho bastante importante: nada se copia realmente cuando se genera el proceso secundario. Esto supondría una gran pérdida de rendimiento, dado que la bifurcación ocurre muy a menudo en Unixes (prácticamente cada vez que genera un nuevo proceso). El mecanismo preciso se basa en "fallas de página". Es posible que desee leer sobre ellos si está interesado. –

+0

bien, entonces ¿cómo podemos obtener la dirección real de esa var y no la virtual? (Preguntando solo para satisfacer mi curiosidad) – buch11

+1

@ buch11: Creo que no puedes, pero voy a permitir que los expertos confirmen. De todos modos, no deberías. Este tipo de información solo es conocida por el kernel, y solo le permitirá acceder a las direcciones locales del proceso. Esto se conoce como "memoria protegida". Cada proceso solo puede acceder a su propia memoria. –

2

Las direcciones son procesos locales (Dicho sea de paso VM también causa código para ser compartida entre el proceso en la memoria física, y todos los datos sólo será copied-on-write.). 804a01c en un proceso no es lo mismo que 804a01c en otro proceso.

2

Debido a virtual memory: ambos espacios de direcciones se ven idénticos a los procesos respectivos. La memoria física en la que están almacenados es diferente. Sin embargo, esto es, en la práctica, complicado por una optimización de memoria (implementada por la mayoría de los kernels) que mapea las páginas virtuales correspondientes a las mismas páginas físicas hasta que uno de esos procesos escribe en esa página de memoria, en ese momento la página se duplica físicamente a otra dirección física (y la página virtual se reasigna para el proceso).

También hay muchas otras complicaciones: la más reconocida es que el valor de retorno de fork() difiere entre los procesos, aunque eso suele ser una diferencia en un valor de registro, no en la memoria. Sin embargo, los archivos abiertos y algunos otros recursos se pueden marcar como no heredables, por lo que podría haber otras diferencias — menores pero a veces útiles.

Cuestiones relacionadas