stringtranslate.com

Ejecución de bifurcación

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 a 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, lo que incluye 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 utilizando la exec()llamada al sistema.

Cuando un proceso se bifurca, se crea una copia completa del programa en ejecución en el nuevo proceso. Este nuevo proceso es un proceso secundario del proceso primario y tiene un nuevo identificador de proceso (PID). La fork()función devuelve el PID del proceso secundario al proceso primario. La fork()función devuelve 0 al proceso secundario. Esto permite que los dos procesos, que de otro modo serían idénticos, se distingan entre sí.

El proceso padre puede continuar la ejecución o esperar a que el proceso hijo termine. El hijo, después de descubrir que es el hijo, generalmente se reemplazará completamente por otro programa, de modo que se perderá 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 en cuestión y, por lo tanto, no es un paso obligatorio en la vida del proceso hijo.

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

También se puede esperar de forma asincrónica a que los hijos terminen, utilizando un controlador de señales para SIGCHLD , si se necesita garantizar que todo esté limpio. Aquí hay un ejemplo de un controlador de señales que captura cualquier señal SIGCHLD entrante y maneja múltiples señales recibidas simultáneamente.

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

Cuando el proceso hijo llama a exec(), se pierden todos los datos del programa original 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 archivo que estaban abiertos en el padre se cierran solo si el programa los ha marcado explícitamente como cerrados en ejecución . Esto permite la práctica común de que el padre cree una tubería antes de llamar fork()y la use para comunicarse con el programa ejecutado.

Microsoft Windows no admite 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 reemplazarlo en los casos en que la llamada a fork()es seguida directamente por exec().

Cuando se realiza una llamada al sistema de bifurcación en WSL , lxss.sys realiza parte del trabajo inicial para preparar la copia del proceso. Luego, llama a las API internas de NT para crear el proceso con la semántica correcta y crea un subproceso 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".