De la página del manual de vfork()
:
vfork () difiere de fork () en que el padre está suspendido hasta que el niño hace una llamada a execve (2) o _exit (2). El hijo comparte toda la memoria con su padre, incluida la pila, hasta que el hijo emita execve (). El hijo no debe regresar de la función actual o de la llamada a exit (), pero puede llamar a _exit ().
¿Por qué el niño debe usar un en _exit()
lugar de simplemente llamar exit()
? Espero que esto sea aplicable a ambos vfork()
y fork()
.
c
system-calls
fork
exit
Sen
fuente
fuente
Respuestas:
Como se vio anteriormente ,
vfork
no permite que el proceso secundario acceda a la memoria de los padres.exit
es una función de biblioteca C (es por eso que a menudo se escribe comoexit(3)
). Realiza varias tareas de limpieza, como enjuagar y cerrar flujos C (los archivos se abren a través de funciones declaradas enstdio.h
) y ejecutar funciones especificadas por el usuario registradas enatexit
. Todas estas tareas implican leer y escribir en la memoria del proceso._exit
sale sin limpieza. Es directamente una llamada al sistema (es por eso que se escribe como_exit(2)
), generalmente implementada colocando el número de llamada del sistema en un registro del procesador y ejecutando una instrucción de procesador particular (bifurcación al manejador de llamadas del sistema). Esto no necesita acceder a la memoria del proceso, por lo que es seguro hacerlo despuésvfork
.Después
fork
, no existe tal restricción: el proceso padre e hijo ahora son completamente autónomos.fuente
init
es bifurcado por el núcleo).exit
realice una limpieza adicional, como llamar a funciones registradas poratexit
lo que accede a datos fuera de la parte copiada._exit
realiza syscall directamente sin ninguna limpieza excepto en el núcleo.fuente
Tiene el elemento secundario call _exit () para evitar el vaciado de buffers stdio (u otros) cuando finaliza el proceso secundario. Dado que el proceso hijo constituye una copia exacta del proceso padre, el proceso hijo todavía tiene lo que el padre tenía en "stdout" o "stderr", los almacenamientos intermedios de <stdio.h>. Puede (y lo hará, en momentos inoportunos) obtener salidas dobles llamando a exit (), una desde los controladores atexit del proceso hijo y otra desde el padre, cuando los buffers en el proceso padre se llenan y se vacían.
Me doy cuenta de que la respuesta anterior se concentra en los detalles de stdio.h, pero esa idea probablemente se traslade a otras E / S almacenadas, tal como indica una de las respuestas anteriores.
fuente
exit()
: realiza una tarea de limpieza, como cerrar las secuencias de E / S y muchas, y luego vuelve al núcleo._exit()
: - llega directamente al kernel (no realice ninguna tarea de limpieza).fork()
: tanto el padre como el hijo tienen una tabla de archivos diferente, por lo que el cambio realizado por el hijo no afecta los parámetros del entorno del padre y viceversa.vfork()
: tanto el padre como el hijo usan la misma tabla de archivos, por lo que el cambio realizado por el hijo afecta los parámetros del entorno del padre. por ejemplo, alguna variablevar=10
, ahora ejecutadavar++
por hijo y luego ejecutada principal, también puede ver el efectovar++
en la salida de principal.Como ya he dicho si se utiliza
exit()
en lavfork()
entonces toda la E / S ya está cerrado. Entonces, incluso si el padre se ejecuta correctamente, no puede obtener la salida adecuada, porque todas las variables se vacían y todas las secuencias están cerradas.fuente