¿Cuándo llamar a fork () y exec () por sí mismos?

9

Estoy aprendiendo sobre los comandos fork () y exec (). Parece que fork () y exec () generalmente se llaman juntos. (fork () crea un nuevo proceso hijo, y exec () reemplaza la imagen del proceso actual por una nueva). Sin embargo, ¿en qué escenarios podría llamar a cada función por sí solo? ¿Hay escenarios como estos?

quil
fuente
2
Bifurcación tradicional: while (1) fork (); acaparar los recursos del sistema.
Joshua

Respuestas:

22

¡Por supuesto! Un patrón común en los programas de "envoltura" es hacer varias cosas y luego reemplazarse por algún otro programa con solo una execllamada (sin bifurcación)

#!/bin/sh
export BLAH_API_KEY=blub
...
exec /the/thus/wrapped/program "$@"

Un ejemplo real de esto es GIT_SSH(aunque git(1)también se ofrece GIT_SSH_COMMANDsi no desea hacer el método del programa contenedor anterior).

Fork-only se usa cuando se generan un montón de procesos típicamente de trabajo (por ejemplo, Apache httpden modo fork) (aunque fork-only se adapta mejor a los procesos que necesitan quemar la CPU y no a aquellos que hacen girar sus pulgares esperando que suceda la E / S de red) ) o para la separación de privilegios utilizada por sshdy otros programas en OpenBSD (sin ejecutivo)

$ doas pkg_add pstree
...
$ pstree | grep sshd
 |-+= 70995 root /usr/sbin/sshd
 | \-+= 28571 root sshd: jhqdoe [priv] (sshd)
 |   \-+- 14625 jhqdoe sshd: jhqdoe@ttyp6 (sshd)

El rootsshd tiene en la conexión del cliente una bifurcación de sí mismo (28571) y luego otra copia (14625) para la separación de privilegios.

thrig
fuente
14

Hay bastantes.

Los programas que llaman fork()sin exec(), generalmente siguen un patrón de generación de procesos de trabajo infantil para realizar diversas tareas en procesos separados al principal. Usted encontrará esto en programas tan variados como dhclient, php-fpm, y urxvtd.

Un programa que llama exec()sin fork()es la carga de la cadena , la superposición de su proceso de imagen un programa diferente con. Hay toda una subcultura de utilidades de carga en cadena que hacen cosas particulares para procesar el estado y luego ejecutan otro programa para ejecutar con ese estado de proceso revisado. Tales utilidades son comunes en la familia de servicios de daemontools y los conjuntos de herramientas de administración del sistema, pero no se limitan a ellos. Algunos ejemplos:

Los conjuntos de herramientas de la familia daemontools tienen muchas de estas herramientas, de machineenvprincipio find-matching-jvma fin runtool.

JdeBP
fuente
2

Además de otras respuestas, los depuradores, que usan ptrace, generalmente hacen uso de la brecha entre forky exec. Un depurador debe marcarse PTRACE_TRACEMEpara indicar que está siendo rastreado por su proceso padre: el depurador. Esto es para otorgar los permisos necesarios al depurador.

Entonces, un depurador primero se bifurcaría. El niño llamaría ptracecon PTRACE_TRACEMEy luego llamaría exec. Cualquiera que sea el programa, el padre y la madre del niño podrán rastrearlo.

bytefire
fuente
Hay muchos ejemplos de hacer cosas entre fork y exec, el más común es redirigir E / S (por ejemplo, configurar tuberías). Pero la pregunta es sobre hacer una bifurcación sin ningún ejecutivo en absoluto.
Barmar
0

ejecutivo sin tenedor

Hay al menos dos razones por las que querrías hacer algo así:

  1. Cadena de carga. La imagen del proceso actual se reemplaza con algo diferente.
  2. Reiniciar el programa que se está ejecutando actualmente (por ejemplo, puede ocurrir cuando SIGHUP o un proceso de servidor de este tipo, vuelve a cargar todo y comienza de nuevo). De alguna manera, uno podría argumentar que esto es carga en cadena, solo coincidentemente con el mismo programa.

tenedor sin ejecutivo

Eso es lo que hace cada demonio cada vez que se inicia (dos veces, de hecho). Esto hace varias cosas, entre ellas el shell no se cuelga (ya que el proceso original en el que el shell espera termina) y el demonio ya no está controlado por el terminal, por lo que cerrar la ventana del shell no mata al demonio.

Otro uso común es bifurcar a los niños trabajadores, que se hizo famoso por el servidor web Apache hace unos 25 años (hoy en día esto ya no se considera de vanguardia debido a que es muy propenso al problema del rebaño atronador, pero ciertamente proporciona el El servidor más simple y robusto posible).

Sin embargo, otro uso común es crear una instantánea consistente. forkno solo crea un proceso, también copia (en teoría, en realidad solo marca páginas copiadas en escritura) el espacio de direcciones. Esto (atómicamente) crea una instantánea de los datos completos del programa que el padre ya no puede modificar.
Algunos programas se aprovechan de eso. Por ejemplo, redis guarda datos en el disco (en un estado coherente) y al mismo tiempo modifica el conjunto de datos simultáneamente. Esto solo funciona porque forkcreó una instantánea consistente que no ve las modificaciones realizadas por el proceso padre.

Damon
fuente
En realidad, son muy pocos demonios hoy en día, y la mayoría no lo hace como estándar o no tiene un modo de uso común. Es un error bifurcar que conduce a desajustes de preparación y horrores , y es uno de los errores de la falacia de demonización . Este error por fin ha caído en desgracia.
JdeBP