[Repetiré parte de mi respuesta desde aquí .]
¿Por qué no simplemente tener un comando que crea un nuevo proceso desde cero? ¿No es absurdo e ineficiente copiar uno que solo será reemplazado de inmediato?
De hecho, eso probablemente no sería tan eficiente por algunas razones:
La "copia", producido por fork()
un poco de una abstracción, ya que el núcleo utiliza una copia en escritura del sistema ; todo lo que realmente tiene que crearse es un mapa de memoria virtual. Si la copia llama inmediatamente exec()
, la mayoría de los datos que se habrían copiado si hubiera sido modificada por la actividad del proceso en realidad nunca tienen que copiarse / crearse porque el proceso no hace nada que requiera su uso.
Varios aspectos importantes del proceso secundario (p. Ej., Su entorno) no tienen que duplicarse o establecerse individualmente en función de un análisis complejo del contexto, etc. Simplemente se supone que son los mismos que los del proceso de llamada, y Este es el sistema bastante intuitivo con el que estamos familiarizados.
Para explicar el # 1 un poco más, la memoria que se "copia" pero nunca se accede posteriormente nunca se copia realmente, al menos en la mayoría de los casos. Una excepción en este contexto podría ser si bifurcas un proceso y luego haces que el proceso principal salga antes de que el secundario se reemplace por sí mismo exec()
. Digo podría porque gran parte del padre podría almacenarse en caché si hay suficiente memoria libre, y no estoy seguro de hasta qué punto esto se explotaría (lo que dependería de la implementación del sistema operativo).
Por supuesto, eso no hace que el uso de una copia sea más eficiente que el uso de una pizarra en blanco, excepto que "la pizarra en blanco" no es literalmente nada y debe implicar la asignación. El sistema podría tener una plantilla de proceso genérica en blanco / nueva que copia de la misma manera, 1 pero que en realidad no ahorraría nada frente a la bifurcación de copia en escritura. De modo que el n. ° 1 simplemente demuestra que usar un "nuevo" proceso vacío no sería más eficiente.
El punto n. ° 2 explica por qué el uso de la bifurcación es probablemente más eficiente. El entorno de un niño se hereda de su padre, incluso si es un ejecutable completamente diferente. Por ejemplo, si el proceso principal es un shell y el secundario un navegador web, $HOME
sigue siendo el mismo para ambos, pero dado que cualquiera de ellos podría cambiarlo posteriormente, deben ser dos copias separadas. El del niño es producido por el original fork()
.
1. Una estrategia que puede no tener mucho sentido literal, pero mi punto es que crear un proceso implica más que copiar su imagen en la memoria del disco.