stringtranslate.com

tenedor-ejecutivo

Fork-exec es una técnica comúnmente utilizada en Unix mediante la cual un proceso en ejecución genera un nuevo programa.

Descripción

fork()es el nombre de la llamada al sistema que el proceso padre utiliza para "dividirse" ("bifurcar") en dos procesos idénticos. Después de llamar fork(), el proceso hijo creado es una copia exacta del padre, excepto por el valor de retorno de la llamada fork(). Esto incluye archivos abiertos, estado de registro y todas las asignaciones de memoria, que incluyen el código ejecutable del programa. En algunos casos, los dos continúan ejecutando el mismo binario, pero a menudo uno (generalmente el hijo) cambia a ejecutar otro ejecutable binario usando la exec()llamada al sistema.

Cuando un proceso se bifurca, se realiza una copia completa del programa en ejecución en el nuevo proceso. Este nuevo proceso es hijo del proceso principal y tiene un nuevo identificador de proceso (PID). La fork()función devuelve el PID del niño al proceso padre. La fork()función devuelve 0 al proceso hijo. Esto permite distinguir entre sí dos procesos por lo demás idénticos.

El proceso principal puede continuar la ejecución o esperar a que se complete el proceso secundario. El niño, después de descubrir que es el niño, lo más frecuente es que se reemplace completamente con otro programa, de modo que se pierda el código y el espacio de direcciones del programa original. Sin embargo, este reemplazo es una elección de la arquitectura sobre la que se construye el programa dado y, por lo tanto, no es un paso obligatorio en la vida del proceso hijo.

Si el padre elige esperar a que el niño muera, recibirá el código de salida del programa que ejecutó el niño. Para evitar que el niño se convierta en un zombi , el padre debe llamar a esperar a sus hijos, ya sea periódicamente o al recibir la señal SIGCHLD , que indica que un proceso secundario ha terminado.

También se puede esperar asincrónicamente a que sus hijos terminen, utilizando un controlador de señales para SIGCHLD , si necesitan asegurarse de que todo esté limpio. A continuación se muestra un ejemplo de un controlador de señales que capta cualquier señal SIGCHLD entrante y maneja múltiples señales simultáneas recibidas.

 limpieza de vacío ( señal int ) { while ( waitpid (( pid_t ) ( -1 ), 0 , WNOHANG ) > 0 ) {} }            

Cuando el proceso hijo llama a exec(), todos los datos del programa original se pierden y se reemplazan con una copia en ejecución del nuevo programa. Esto se conoce como superposición . Aunque se reemplazan todos los datos, los descriptores de archivos que estaban abiertos en el padre se cierran solo si el programa los ha marcado explícitamente como close-on-exec . Esto permite la práctica común de que el padre cree una tubería antes de llamarla fork()y usarla para comunicarse con el programa ejecutado.

Microsoft Windows no es compatible con el modelo fork-exec, ya que no tiene una llamada al sistema análoga a fork(). La spawn()familia de funciones declaradas en Process.h puede reemplazarla en los casos en que la llamada a fork()va seguida directamente de exec().

Cuando se realiza una llamada al sistema fork en WSL , lxss.sys realiza parte del trabajo inicial para prepararse para copiar el proceso. Luego llama a las API internas de NT para crear el proceso con la semántica correcta y crear un hilo en el proceso con un contexto de registro idéntico. Finalmente, realiza un trabajo adicional para completar la copia del proceso y reanuda el nuevo proceso para que pueda comenzar a ejecutarse.

—  Jack Hammons de Microsoft [1]

Referencias

  1. ^ "Llamadas al sistema WSL".