Deberías usar _exit
(o su sinónimo _Exit
) para abortar el programa hijo cuando exec
falla, porque en esta situación, el proceso secundario puede interferir con los datos externos (archivos) del proceso principal llamando a su atexit
manejadores, llamando a sus manejadores de señales y/o descargando búferes.
Por la misma razón, también deberías usar _exit
en cualquier proceso hijo que no haga un exec
, pero esos son raros.
En todos los demás casos, simplemente use exit
. Como usted mismo notó parcialmente, cada proceso en Unix/Linux (excepto uno, init
) es hijo de otro proceso, por lo que usar _exit
en cada proceso hijo significaría que exit
es inútil fuera de init
.
switch (fork()) {
case 0:
// we're the child
execlp("some", "program", NULL);
_exit(1); // <-- HERE
case -1:
// error, no fork done ...
default:
// we're the parent ...
}
exit()
vacía los búferes de io y hace otras cosas como ejecutar funciones registradas por atexit()
. exit()
invoca _end( )
_exit()
acaba de terminar el proceso sin hacer eso. Llamas al _exit()
del proceso principal al crear un demonio, por ejemplo.
¿Alguna vez has notado que main()
es una función? ¿Alguna vez se preguntó qué lo llamó en primer lugar? Cuando un programa C ejecuta el shell en el que está ejecutando, proporciona la ruta ejecutable a la llamada del sistema 'ejec' y el control se pasa al núcleo, que a su vez llama a la función de inicio de cada _start()
, llama a tu main()
, cuando main()
lo devuelve y luego llama a _end()
Algunas implementaciones de C usan nombres ligeramente diferentes para _end()
&_start()
...
exit()
y _exit()
invocar _end()
Normalmente, por cada main()
debe haber uno y solo uno exit()
llamar. (o regresar al final de main()
)
exit() está en la parte superior de _exit(), usando la biblioteca C convencional.
Estas son las diferencias:
-
_exit() no vaciará el búfer de stdio mientras que exit() vaciará el búfer de stdio antes de salir.
-
_exit() no puede realizar el proceso de limpieza, mientras que exit() puede registrarse con alguna función (es decir, on_exit o at_exit) para realizar algún proceso de limpieza si se requiere algo antes de que exista el programa.
exit(status) simplemente pasa el estado de salida a _exit(status). Se recomienda que siempre que se realice fork(), uno de ellos entre child y parent, uno use _exit() y otro use exit().