¿Cuál es la diferencia entre fork()
y vfork()
? ¿Devuelve vfork()
como fork()
?¿Cuál es la diferencia entre fork() y vfork()?
Respuesta
La intención de vfork
fue eliminar la sobrecarga de la copia de la imagen de proceso entera si sólo desea hacer una exec*
en el niño. Como exec*
reemplaza la imagen completa del proceso secundario, no tiene sentido copiar la imagen del elemento primario.
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 kernels actuales, incluido Linux, el beneficio principal de vfork
ha desaparecido debido a la forma en que se implementa fork
. En lugar de copiar toda la imagen cuando se ejecuta fork
, se utilizan técnicas de copiado por escritura.
Los sistemas basados en BSD todavía tienen una función real * vfork *. Lee la fuente. – tchrist
Linux también tiene un 'vfork real (2)'. En general, supongo que cada * nix que ha sido portado a plataformas que no son MMU tiene un 'vfork real (2)' real. – ninjalj
Importante para tener en cuenta * técnicas de copiado sobre escritura *. La memoria se copia solo si el nuevo proceso intenta modificarla. muy crítico para sistemas como Android. –
Desde mi página de manual
(De POSIX.1) La función vfork() tiene el mismo efecto que el tenedor (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 usada para almacenar el valor de retorno de vfork(), o devuelve de la función en la que se llamó vfork() o llama a cualquier otra función antes de llamar con éxito _exit (2) o uno de los exec (3) fam il de funciones.
vfork() difiere de tenedor (2) en que el padre se suspende hasta que el niño termina (ya sea normalmente, por llamando _exit (2), o anormalmente, después de la entrega de una señal fatal), o hace una llamada a execve (2). Hasta ese momento, el hijo comparte toda la memoria con su padre, incluida la pila. El niño no debe devolver desde el la función actual o llamar a exit (3), , pero puede llamar a _exit (2).
+1 páginas RTF man. Además, el enlace xkcd desde que xkcd tiene un cómic para * cada * ASUNCIÓN: http://xkcd.org/293 – delnan
También vale la pena señalar que 'vfork()' es principalmente un artefacto histórico: en los sistemas modernos con copia sana -write semántica, 'vfork()' generalmente no gana mucho (si es que algo, a veces es esencialmente un alias para 'fork()'!). –
Como ya se indicó, la página de manual de vfork
es clara sobre las diferencias. Este topic da una buena descripción de fork
, vfork
, clone
y exec
.
A continuación se presentan algunas diferencias que a menudo se pasan por alto entre fork
y vfork
que experimenté en algunos sistemas embebidos Linux 2.6.3x con los que trabajé.
Incluso con las técnicas de copiado en escritura, 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), 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 enorme 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 al exec*
o _exit
sin dañar el proceso principal.
Debido a las tablas de páginas de memoria no se duplican, vfork
es mucho más rápido que fork
y tiempo de ejecución vfork
's no se ve afectada por la cantidad de memoria utilizada por el proceso padre, como se ha señalado aquí: http://blog.famzah.net/2009/11/20/fork-gets-slower-as-parent-process-use-more-memory/
en situaciones en las el rendimiento es crítico y/o la memoria limitada, vfork
+ exec*
puede por lo tanto ser una buena alternativa a fork
+ exec*
. El problema es que es menos seguro y la página de manual dice vfork
es probable que quede obsoleto en el futuro.
Una solución más segura y portátil puede ser observar la función posix_spawn
, que es de mayor nivel y ofrece más opciones. Usa de manera segura vfork
cuando sea posible, dependiendo de las opciones que pase. He podido usar posix_spawn
con éxito y superar ese molesto "problema de doble verificación de memoria" que fork
+ exec
me estaba dando.
A really good page on this topic, with links to some posix_spawn
examples.
Incidentalmente, 'Runtime.exec()' de Java ha utilizado tradicionalmente 'fork()/exec()', pero IIRC Java 1.7 usará 'vfork()/exec()' o 'posix_spawn()' donde esté disponible. – ninjalj
Algunos sistemas tienen un vfork llamada al sistema(), que fue diseñado originalmente como una versión de menor sobrecarga de tenedor(). Como 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 ambos procesos hacen referencia 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 completamente de la funcionalidad original de vfork(). Sin embargo, para compatibilidad, todavía puede haber una llamada vfork() presente, que simplemente llama a fork() sin intentar emular toda la semántica 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 se cierra 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 la modificación inesperada de las variables del 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 diferencia básica entre los dos es que cuando se crea un nuevo proceso con vfork()
, el proceso padre 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 se cierra o llama al execve()
, momento en el que continúa el proceso principal.
Esto significa que el proceso secundario de vfork()
debe tener cuidado al evitar la modificación inesperada de las variables del proceso principal. En particular, el proceso hijo no debe regresar a la función que contiene la llamada vfork()
, y no debe llamar exit()
(si tiene que salir, se debe utilizar _exit();
realidad, esto también es cierto para el niño de un normales fork()
).
Sin embargo, desde vfork()
se introdujo, el implementación de fork()
ha mejorado drásticamente, sobre todo con la introducción de 'copia en escritura', , donde la copia del espacio de direcciones proceso es transparente falsificada al permitir ambos procesos para referirse a la misma memoria física hasta que cualquiera de ellos modifique . Esto elimina en gran parte la justificación de vfork();
de hecho, una gran proporción de sistemas ahora carecen completamente de la funcionalidad original de vfork()
. Por compatibilidad, sin embargo, todavía puede haber una llamada vfork()
presente, que simplemente llama a fork()
sin intentando emular toda la semántica vfork()
.
Como resultado, es muy imprudente utilizar realmente cualquiera de las diferencias entre fork()
y vfork()
. De hecho, es probablemente imprudente usar vfork()
en absoluto, a menos que sepa exactamente por qué desea hacerlo.
- 1. ¿Cuál es la diferencia entre llamar a daemon() y llamar a fork(), setsid(), fork(), etc.?
- 2. diferencia entre fork y branch en github
- 3. ¿Cuál es la diferencia entre {0} y ""?
- 4. Cuál es la diferencia entre = y: =
- 5. ¿Cuál es la diferencia entre .ToString (+) y ""
- 6. Cuál es la diferencia entre $ (...) y `...`
- 7. ¿cuál es la diferencia entre:.! y: r !?
- 8. ¿Cuál es la diferencia entre ".equals" y "=="?
- 9. ¿Cuál es la diferencia entre dict() y {}?
- 10. ¿Cuál es la diferencia entre `##` y `hashCode`?
- 11. ¿Cuál es la diferencia entre "$^N" y "$ +"?
- 12. ¿Cuál es la diferencia entre [indefinido] y [,]?
- 13. ¿Cuál es la diferencia entre + = y = +?
- 14. ¿Cuál es la diferencia entre " " y ""?
- 15. Cuál es la diferencia entre $ y jQuery
- 16. OpenGL (ES) - ¿Cuál es la diferencia entre frustum y orto?
- 17. Cuál es la diferencia entre la función() {}() y la función() {}()
- 18. ¿Cuál es la diferencia entre la abstracción y la encapsulación?
- 19. ¿Cuál es la diferencia entre @ y $ y% en MSBuild?
- 20. ¿Cuál es la diferencia entre la vinculación estática y dinámica?
- 21. ¿Cuál es la diferencia entre la sección .got y .got.plt?
- 22. ¿Cuál es la diferencia entre el colado y la coerción?
- 23. ¿cuál es la diferencia entre el complemento y la biblioteca?
- 24. ¿Cuál es la diferencia entre el casting y la conversión?
- 25. ¿Cuál es la diferencia entre WPF y la aplicación Silverlight?
- 26. ¿Cuál es la diferencia entre uno mismo y la ventana?
- 27. ¿Cuál es la diferencia entre CookieContainer y la colección Response.Cookies?
- 28. ¿Cuál es la diferencia entre la relación Composición y Asociación?
- 29. ¿cuál es la diferencia entre el material y la textura?
- 30. ¿Cuál es la diferencia entre el marco y la arquitectura?
* fork * significa Funciones en Núcleos Reales. * vfork * significa Funciones Vicariamente en Núcleos Reales. – tchrist