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.
- 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.
- ¿Esto
fork
yexec
el 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? - ¿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.
Respuestas:
No exactamente.
fork()
clona el proceso actual, creando un hijo idéntico.exec()
carga un nuevo programa en el proceso actual, reemplazando el existente.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.
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 esexec
, que le dice al shell alexec()
programa externo sin primerofork()
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 true
y luego/bin/true
va 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.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.fuente
cd
oread
podrían funcionar. La falta de bifurcar también hace órdenes internas mucho más rápido que los comandos externos.execve()
para superponerse con un código diferente.fork()
y seexec()
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 generalizacionesfork()
, como BSDvfork()
, Plan 9rfork()
y Linux 'clone()
, pero el principal sigue siendo el mismo.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.fuente
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
fork
llamada 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 simplementeexec
ingresar a otro ejecutable después de todo.fork
+exec
por 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í
vfork
nació.fuente
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.
fuente