¿Cómo funcionan fork y exec?

17

No tengo mucha experiencia, solo intento involucrarme en los procesos, ¿cómo interpretan el hardware desde el nivel de usuario?

Entonces, cuando un comando se dispara desde un shell, fork()hereda un proceso secundario del mismo y exec()carga el proceso secundario en la memoria y se ejecuta.

  1. Si el proceso secundario contiene todos los atributos del proceso primario (que es el proceso original), ¿cuál es la necesidad de este proceso secundario? El proceso original también podría haberse cargado en la memoria.
  2. ¿Esto forky execel concepto se aplica a todo el programa ejecutable en UNIX? ¿Te gusta el script de shell también o solo los comandos? ¿También se aplica a los comandos integrados de shell?
  3. ¿Cuándo se usa el concepto de copia en escritura si voy a ejecutar un comando / script?

Perdón por hacer muchas preguntas a la vez, pero todas estas preguntas se me ocurren de inmediato cuando pienso en la ejecución de cualquier comando.

PriB
fuente
No voy a decir que esto es un duplicado, pero creo que algunos de su pregunta se contesta aquí: unix.stackexchange.com/questions/136637/... y en la otra respuesta ligado en la parte superior de aquél.
Ricitos

Respuestas:

22

Entonces, cuando se dispara un comando desde un shell, fork () hereda un proceso secundario del mismo y exec () carga el proceso secundario en la memoria y se ejecuta.

No exactamente. fork()clona el proceso actual, creando un hijo idéntico. exec()carga un nuevo programa en el proceso actual, reemplazando el existente.

Mi qs es:

Si el proceso secundario contiene todos los atributos del proceso primario (que es el proceso original), ¿cuál es la necesidad de este proceso secundario? El proceso original también podría haberse cargado en la memoria.

La necesidad se debe a que el proceso padre aún no desea finalizar; quiere que se inicie un nuevo proceso y haga algo al mismo tiempo que continúa ejecutándose también.

¿Este concepto fork y exec se aplica a todos los programas ejecutables en UNIX? ¿Al igual que para el script de shell también o solo para los comandos? ¿También se aplica a los comandos integrados de shell?

Para los comandos externos, el shell hace un fork()comando para que el comando se ejecute en un nuevo proceso. Las construcciones solo son ejecutadas por el shell directamente. Otro comando notable es exec, que le dice al shell al exec()programa externo sin primero fork()ing. Esto significa que el propio shell se reemplaza con el nuevo programa y, por lo tanto, ya no está allí para que ese programa regrese cuando salga. Si usted dice, exec truey luego /bin/trueva a reemplazar su cáscara, y de inmediato la salida, sin dejar nada que se ejecuta en su terminal más, así que se va a cerrar.

cuando se utiliza el concepto de copia en escritura si voy a ejecutar un comando / script?

De vuelta en la edad de piedra, fork()de hecho tuvimos que copiar toda la memoria en el proceso de llamar al nuevo proceso. Copiar al escribir es una optimización en la que las tablas de páginas se configuran para que los dos procesos comiencen a compartir toda la misma memoria, y solo las páginas en las que cada proceso escribe se copian cuando sea necesario.

psusi
fuente
44
"Para casi todos los comandos, el shell hace una bifurcación () para que el comando se ejecute en un nuevo proceso. Si ese comando está incorporado, entonces el niño no necesita ejecutar () un programa separado". Buena respuesta, pero esta parte debería ser editada. El caparazón no se bifurca cuando se ejecutan los acumuladores. Los ejecuta directamente en el proceso de shell activo. Esta es la única forma en que a los integrantes les gusta cdo readpodrían funcionar. La falta de bifurcar también hace órdenes internas mucho más rápido que los comandos externos.
John Kugelman apoya Mónica
6
  1. Para algunos programas, el proceso secundario hace una cosa (leer desde un puerto serie, escribir en el terminal), y el proceso principal continúa haciendo otra cosa (leer desde la terminal, escribir en el puerto serie). Otro ejemplo clásico es el proceso hijo hace un retén de cualquier cálculo de larga duración está teniendo lugar. En su mayoría, el proceso secundario realiza alguna configuración, como cambiar el directorio, restablecer los controladores de señales o restablecer los descriptores de archivos, y luego llama execve()para superponerse con un código diferente.
  2. fork()y se exec()aplican a todos los ejecutables; de hecho, junto con argc y argv, y las tuberías, fork y exec son lo que distingue a Unix de otros sistemas operativos. Existen algunas especializaciones o generalizaciones fork(), como BSD vfork(), Plan 9 rfork()y Linux ' clone(), pero el principal sigue siendo el mismo.
  3. "copiar al escribir" realmente no se muestra al usuario, es más una técnica para optimizar la creación de un proceso hijo y durante su ejecución. La pila de llamadas y el montón (memoria asignada con malloc(), o incluso variables de alcance estáticas o globales) pueden ser "copia al escribir". Cuando un proceso hijo se crea con unafork()llamada, el núcleo sería configurar el proceso hijo tenga las mismas páginas exactas de la memoria como pila y pila que el proceso padre. Si el hardware (unidad de gestión de memoria) detecta una escritura del montón o pila, el núcleo sería conseguir una nueva página física de la memoria, copia de la página de los padres en la nueva página, y el mapa de la nueva página en la pila o montón del proceso hijo. Esto constituye una optimización ya que el kernel pasa menos tiempo configurando asignaciones de páginas que copiar la pila y el montón por completo para el proceso secundario.
Bruce Ediger
fuente
Gracias Bruce por su respuesta. Pero hay tantas cosas que has dicho aquí que se me pasan por la cabeza. No tengo mucho conocimiento con estas cosas ... Intentaré hacer que estas funciones funcionen como has mencionado. Muchas gracias..!!
PriB
4
Si el proceso secundario contiene todos los atributos del proceso primario (que es el proceso original), ¿cuál es la necesidad de este proceso secundario? El proceso original también podría haberse cargado en la memoria.

Esta pregunta es muy ilustrativa contestada por echar un vistazo a las primeras implementaciones de Unix, que tuvo que trabajar bajo restricciones severas de memoria y sólo tenía un proceso en ejecución en el espacio de memoria / dirección a la vez.

La multitarea se logró intercambiando un proceso al disco e intercambiando un proceso diferente.

Ahora la forkllamada del sistema era casi la misma: intercambió un proceso en el disco, pero en lugar de intercambiar otro proceso, le dio a la copia en memoria otro id de proceso y regresó a él. Y ese fue un momento oportuno para que este proceso decidiera simplemente execingresar a otro ejecutable después de todo.

fork+ execpor lo tanto, en realidad no incurrió en una sobrecarga notable por el desove: tuvo que cambiar su proceso al disco de todos modos, y de todos modos tenía la imagen del proceso anterior en ubicaciones de memoria factibles.

Con cantidades crecientes de unidades de memoria y gestión de memoria disponibles y múltiples procesos en memoria, el costo inicialmente insignificante de una bifurcación se convirtió en una molestia para algunas arquitecturas: así vforknació.

user99727
fuente
2

Para hacer esto lo más fácil de entender posible, usaré una analogía. ¡Horneemos un pastel!

Tomamos el libro de recetas, comenzamos a leer y nos acomodamos en un pastel de ruibarbo de fresa (mi favorito), con una corteza hecha a mano. Casi todo lo que necesitamos está en la cocina, excepto los huevos y la fruta, pero como vivimos en una granja y la fruta está en temporada, esto no es un problema. El problema es que el horno está roto y no hay tiempo suficiente para hacer todo. ¿No sería bueno tener más de uno de mí?

tenedor () al rescate. Ahora hay dos de mí. y los dos nos dirigimos a la cocina para comenzar a hacer la masa de pastel. ¡Uy! Entonces miramos el regreso de fork. Obtuve un gran número, él obtuvo cero, así que me dirijo a la cocina mientras él se dirige al gallinero y al jardín. Cuando paso por el horno, bifurco () nuevamente, miro el valor de retorno: bummer, obtuve cero. Continúa hacia la harina mientras miro fijamente el horno roto. Abro la puerta, no hay luz, cierro la puerta. ¿Alguien sabe cómo arreglar un horno?

exec () al rescate. Alcanzo el voltímetro en mi cinturón de herramientas, la bombilla podría ser diagnóstica, así que verifico la potencia, el interruptor disparado de hecho, la solución fácil. Mientras camino hacia el panel de interruptores, veo a un compañero recogiendo ruibarbo. ¡Qué asco! Prefiero el pastel de chocolate y seda.

Hildred
fuente