Aquí hay un código:
int i = 0; pid_t pid; puts("Hello, World!"); puts(""); pid = fork(); if (pid) { i = 42; } printf("%p\n", &i); printf("%d\n", i); puts("");
y salida
Hello, World! 0x7fffc2490278 42 0x7fffc2490278 0
Impresión del programa ¡Hola, mundo! una vez, por lo que el proceso secundario no se inició desde el principio y no se redefinieron las variables. Las direcciones de las variables son las mismas. Entonces son iguales. Pero cambio el valor de i en el proceso principal que se ejecuta primero, no cambió para el proceso secundario. ¿Por qué?
Las direcciones de las variables son las mismas. Entonces son iguales. Pero cambio el valor de i en el proceso principal que se ejecuta primero, no cambió para el proceso secundario. ¿Por qué?
Las direcciones están en el ámbito de un proceso. Son direcciones virtuales. La dirección 0x7fffc2490278
en el proceso principal y 0x7fffc2490278
en el proceso secundario son direcciones físicas diferentes.
Cuando haces fork()
, se creará un proceso completo que incluye variables. Así que i
en el padre no es i
en el hijo. Tienen la misma dirección virtual pero no la misma dirección física. La modificación es completamente independiente.
De la página del manual para la bifurcación:
En caso de éxito, el PID del proceso hijo se devuelve en el padre y 0 en el hijo. En caso de falla, se devuelve -1 en el padre, no se crea ningún proceso hijo y errno se establece de manera adecuada.
Es decir, para el pid principal se establece en un número mayor que 0 (o -1 si falla, que también debe verificar).
if(pid)
se evalúa como if(true)
Y se ejecutará para el padre. El niño, sin embargo, obtiene 0 asignado a pid
(así es como sabe que es el niño).
if(0)
se evalúa como if(false)
y por lo tanto el valor de i no cambia.
Sin embargo, debido a las abstracciones, el proceso ve la memoria en las direcciones virtuales (espacio de direcciones virtuales que se copia exactamente con la fork
). Solo el kernel puede administrar direcciones físicas y el proceso se comunica con el kernel para obtener esta memoria (el proceso simplemente dice "coloque esta variable i
en esta dirección: 0x7fffc2490278
" y el kernel básicamente la mapeará donde quiera). Por lo que sabe el proceso, es el único proceso que solicita memoria y es por eso que sus direcciones son las "mismas".