sistema que proceso obtener llamadas las funcionamiento estados ejemplo devuelve como comando c unix fork vfork

que - ¿Cuál es la diferencia entre fork() y vfork()?



que devuelve fork (6)

Consulte aquí y desde la wikipedia -

En algunos sistemas, vfork () es lo mismo que fork (). La función vfork () difiere de fork () solo en que el proceso hijo puede compartir código y datos con el proceso de llamada (proceso principal).

¿Cuál es la diferencia entre fork() y vfork() ? vfork() devuelve como fork() .


De mi página man

(Desde POSIX.1) La función vfork () tiene el mismo efecto que fork (2), excepto que el comportamiento no está definido si el proceso creado por vfork () modifica cualquier información que no sea una variable de tipo pid_t utilizada para almacenar el devuelve el valor de vfork (), o lo devuelve de la función a la que se llamó vfork (), o llama a cualquier otra función antes de llamar con éxito _exit (2) o una de las familias de funciones de exec (3).

vfork () difiere de la bifurcación (2) en que el padre se suspende hasta que el niño termina (normalmente, llamando _exit (2), o anormalmente, después de la entrega de una señal fatal), o hace una llamada a execve (2 ) Hasta ese punto, el niño comparte toda la memoria con su padre, incluida la pila. El niño no debe regresar de la función actual o llamar a exit (3), pero puede llamar a _exit (2).


Algunos sistemas tienen una llamada al sistema vfork (), que originalmente se diseñó como una versión de bajo costo de fork (). Dado que fork () implicó copiar todo el espacio de direcciones del proceso, y por lo tanto era bastante caro, se introdujo la función vfork () (en 3.0BSD).

Sin embargo, desde que se introdujo vfork (), la implementación de fork () ha mejorado drásticamente, sobre todo con la introducción de `copy-on-write '', donde la copia del espacio de direcciones de proceso se falsifica de forma transparente permitiendo que ambos procesos se refieran a la misma memoria física hasta que cualquiera de ellos la modifique. Esto elimina en gran medida la justificación de vfork (); de hecho, una gran proporción de sistemas ahora carecen por completo de la funcionalidad original de vfork (). Para compatibilidad, sin embargo, todavía puede haber una llamada vfork () presente, que simplemente llama a fork () sin intentar emular todas las semánticas de vfork ().

Como resultado, es muy imprudente utilizar realmente cualquiera de las diferencias entre fork () y vfork (). De hecho, probablemente no sea prudente usar vfork () en absoluto, a menos que sepa exactamente por qué lo desea.

La diferencia básica entre los dos es que cuando se crea un nuevo proceso con vfork (), el proceso principal se suspende temporalmente, y el proceso secundario puede tomar prestado el espacio de direcciones del padre. Este extraño estado de cosas continúa hasta que el proceso secundario sale o se llama a execve (), en cuyo punto continúa el proceso principal.

Esto significa que el proceso hijo de vfork () debe tener cuidado para evitar variables que se modifiquen inesperadamente en el proceso principal. En particular, el proceso hijo no debe regresar de la función que contiene la llamada vfork (), y no debe llamar a exit () (si necesita salir, debe usar _exit (); en realidad, esto también es cierto para el niño de una horquilla normal ()).


La intención de vfork era eliminar la sobrecarga de copiar toda la imagen del proceso si solo desea hacer un exec* en el niño. Debido a que exec* reemplaza la imagen completa del proceso hijo, no tiene sentido copiar la imagen del padre.

if ((pid = vfork()) == 0) { execl(..., NULL); /* after a successful execl the parent should be resumed */ _exit(127); /* terminate the child in case execl fails */ }

Para otros tipos de usos, vfork es peligroso e impredecible.

Sin embargo, con la mayoría de los núcleos actuales, incluido Linux, el principal beneficio de vfork ha desaparecido debido a la forma en que se implementa fork . En lugar de copiar toda la imagen cuando se ejecuta la fork , se utilizan técnicas de copia por escritura.


La diferencia básica entre los dos es que cuando se crea un nuevo proceso con vfork() , el proceso principal se suspende temporalmente, y el proceso secundario puede tomar prestado el espacio de direcciones del padre. Este extraño estado de cosas continúa hasta que el proceso secundario sale o se llama a execve() , en cuyo punto continúa el proceso principal.

Esto significa que el proceso hijo de vfork() debe tener cuidado para evitar variables que se modifiquen inesperadamente en el proceso principal. En particular, el proceso hijo no debe regresar de la función que contiene la llamada vfork() , y no debe llamar a exit() (si necesita salir, debe usar _exit(); realidad, esto también es cierto para el niño de una fork() normal fork() ).

Sin embargo, desde que se introdujo vfork() , la implementación de fork() ha mejorado drásticamente, más notablemente con la introducción de ''copy-on-write'', donde la copia del espacio de direcciones de proceso se falsifica de manera transparente permitiendo que ambos procesos se refieran a la misma memoria física hasta que cualquiera de ellos la modifique. Esto elimina en gran medida la justificación de vfork(); de hecho, una gran proporción de sistemas ahora carecen por vfork() de la funcionalidad original de vfork() . Para compatibilidad, sin embargo, todavía puede haber una llamada vfork() presente, que simplemente llama a fork() sin intentar emular todas las semánticas de vfork() .

Como resultado, es muy imprudente utilizar realmente cualquiera de las diferencias entre fork() y vfork() . De hecho, probablemente no sea prudente usar vfork() en absoluto, a menos que sepa exactamente por qué lo desea.


Como ya se dijo, la página man de vfork es clara sobre las diferencias. Este tema ofrece una buena descripción de fork , vfork , clone y exec .

A continuación se presentan algunas diferencias a menudo pasadas por alto entre fork y vfork que experimenté en algunos sistemas embebidos Linux 2.6.3x con los que trabajé.

Incluso con técnicas de copiado por escritura, la fork falla si no tiene suficiente memoria para duplicar la memoria utilizada por el proceso principal. Por ejemplo, si el proceso principal usa 2 GB de memoria residente (es decir, memoria que se usa y no solo asignada), la fork falla si tiene menos de 2 GB de memoria libre. ¡Eso es frustrante cuando solo quieres exec un programa simple y por lo tanto nunca necesitarás ese gran espacio de direcciones para padres!

vfork no tiene este problema de memoria, ya que no duplica el espacio de direcciones principal. El proceso hijo actúa más como un hilo en el que puede llamar a exec* o _exit sin dañar el proceso principal.

Debido a que las tablas de páginas de memoria no están duplicadas, vfork es mucho más rápido que fork y el tiempo de ejecución de vfork no se ve afectado por la cantidad de memoria que utiliza el proceso principal, como se señala aquí: http://blog.famzah.net/2009/ 11/20 / fork-gets-slower-as-parent-process-use-more-memory /

En situaciones donde el rendimiento es crítico y / o limitado de memoria, vfork + exec* puede ser una buena alternativa a fork + exec* . El problema es que es menos seguro y la página man dice que es probable que vfork quede obsoleto en el futuro.

Una solución más segura y portátil puede ser mirar la función posix_spawn , que es de nivel superior y ofrece más opciones. Usa vfork forma vfork cuando es posible, dependiendo de las opciones que lo pases. Pude usar posix_spawn éxito y superar ese molesto "problema de doble verificación de memoria" que fork + exec me estaba dando.

Una muy buena página sobre este tema, con enlaces a algunos ejemplos de posix_spawn .