La llamada del sistema UNIX para la creación de procesos, fork(), crea un proceso secundario copiando el proceso principal. Según tengo entendido, esto casi siempre va seguido de una llamada a exec() para reemplazar el espacio de memoria del proceso secundario (incluido el segmento de texto). Copiar el espacio de memoria de los padres en fork() siempre me pareció un desperdicio (aunque me doy cuenta de que el desperdicio se puede minimizar haciendo que los segmentos de memoria se copien sobre escritura para que solo se copien los punteros). De todos modos, ¿alguien sabe por qué se requiere este enfoque de duplicación para la creación de procesos?
Respuesta aceptada:
Es para simplificar la interfaz. La alternativa a fork
y exec
sería algo así como la función CreateProcess de Windows. Observe cuántos parámetros CreateProcess
tiene, y muchos de ellos son estructuras con incluso más parámetros. Esto se debe a que todo es posible que desee controlar el nuevo proceso que debe pasarse a CreateProcess
. De hecho, CreateProcess
no tiene suficientes parámetros, por lo que Microsoft tuvo que agregar CreateProcessAsUser y CreateProcessWithLogonW.
Con el fork/exec
modelo, no necesita todos esos parámetros. En cambio, ciertos atributos del proceso se conservan en exec
. Esto le permite fork
, luego cambie los atributos de proceso que desee (usando las mismas funciones que usaría normalmente) y luego exec
. En Linux, fork
no tiene parámetros, y execve
tiene sólo 3:el programa a ejecutar, la línea de comando para darle, y su entorno. (Hay otros exec
funciones, pero son solo envoltorios alrededor de execve
proporcionada por la biblioteca C para simplificar los casos de uso comunes).
Si desea iniciar un proceso con un directorio actual diferente:fork
, chdir
, exec
.
Si desea redirigir stdin/stdout:fork
, cerrar/abrir archivos, exec
.
Si quieres cambiar de usuario:fork
, setuid
, exec
.
Todas estas cosas se pueden combinar según sea necesario. Si a alguien se le ocurre un nuevo tipo de atributo de proceso, no tiene que cambiar fork
y exec
.
Como mencionó larsks, la mayoría de los Unixes modernos usan copy-on-write, así que fork
no implica una sobrecarga significativa.