NOMBRE¶
vfork - crea un proceso hijo y bloquea al padre
SINOPSIS¶
#include <sys/types.h>
#include <unistd.h>
pid_t vfork(void);
DESCRIPCIÓN ESTÁNDAR¶
(Según XPG4 / SUSv2 / borrador POSIX.) La función
vfork() tiene
el mismo efecto que
fork(), pero el comportamiento es indefinido si el
proceso creado por
vfork() o bien modifica cualquier otro dato que no
sea una variable de tipo pid_t usada para almacenar el valor devuelto por
vfork(), o bien regresa de la función en la que se llamó a
vfork() o bien llama a cualquier otra función antes de llamar con
éxito a
_exit() o a una de las funciones de la familia
exec.
ERRORES¶
- EAGAIN
- Demasiados procesos. Inténtelo de nuevo.
- ENOMEM
- No hay espacio de intercambio suficiente para el nuevo
proceso.
DESCRIPCIÓN DE LINUX¶
vfork, como
fork(2), crea un proceso hijo del proceso invocador.
Para más detalles, valor devuelto y errores, vea
fork(2).
vfork() es un caso especial de
clone(2). Se usa para crear
procesos nuevos sin copiar las tablas de páginas del proceso padre. Puede
ser útil en aplicaciones sensibles al rendimiento donde se creará un
hijo que a continuación realizará inmediatamete una llamada
execve().
vfork() se diferencia de fork en que se suspende al padre hasta que el
hijo hace una llamada
execve(2) o
_exit(2). El hijo comparte con
su padre toda la memoria, incluyendo la pila, hasta que el hijo invoca a
execve(). El hijo no debe regresar de la función actual o llamar a
exit(), pero puede llamar a
_exit().
Los manejadores de señal se heredan pero no se comparten. Las señales
destinadas al padre llegan después de que el hijo lo libere.
DESCRIPCIÓN HISTÓRICA¶
En Linux
fork() se implementa usando páginas de "copia en
escritura", por lo que la única penalización en la que incurre
fork() es el tiempo y memoria necesarios para duplicar las tablas de
páginas del padre y crear una estructura de tarea para el hijo. Sin
embargo, en los malos tiempos, un
fork() requería hacer una copia
completa del espacio de datos del invocador, a menudo de forma inútil ya
que, usualmente, se realizaba inmediatamente después una llamada
exec(). Por tanto, para una mayor eficiencia, BSD introdujo la llamada
al sistema
vfork que no copiaba totalmente el espacio de direcciones
del proceso padre, sino que tomaba prestados la memoria del padre y su hilo de
ejecución hasta que se producía una llamada a
execve() o un
fin de ejecución. El proceso padre se suspendía mientras el hijo
usaba sus recursos. El uso de vfork era delicado (por ejemplo, el no modificar
datos en el proceso padre dependía de saber qué variables se
mantenían en un registro).
FALLOS¶
Es bastante desafortunado que Linux haya revivido este espectro del pasado. La
página de manual de BSD establece: "Esta llamada al sistema se
eliminará cuando se implementen mecanismos del sistema adecuados para
compartición. Los usuarios no deberían confiar en la semántica
de compartición de memoria de
vfork ya que, en ese momento,
será igual a
fork."
Formalmente hablando, la descripción estándar dada antes no permite
usar
vfork() ya que un
exec posterior podría fallar y lo
que a continuación ocurra es indefinido.
Los detalles del manejo de señales son oscuros y difieren entre sistemas.
La página de manual de BSD dice: "Para evitar una posible
situación de abrazo mortal, a aquellos procesos hijos que se encuentran a
mitad de una llamada
vfork nunca se les envía una señal
SIGTTOU o SIGTTIN. En su lugar, se permiten la salida o las
ioctls, y
los intentos de entrada dan lugar a una indicación de "fin de
fichero"."
Actualmente (Linux 2.3.25),
strace(1) no puede seguir un
vfork() y
necesita un parche del núcleo.
HISTORIA¶
La llamada al sistema
vfork() apareció en 3.0BSD. En BSD 4.4 se hizo
sinónima de
fork(), pero NetBSD la introdujo de nuevo,
http://www.netbsd.org/Documentation/kernel/vfork.html. En Linux ha sido
equivalente a
fork() hasta la versión 2.2.0-pre6 más o menos.
Desde la versión 2.2.0-pre9 (en i386, algo más tarde en otras
arquitecturas) es una llamada al sistema independiente. El soporte para esta
llamada se añadió en la versión 2.0.112 de glibc.
La llamada
vfork se puede parecer un poco a las llamadas con el mismo
nombre en otro sistema operativo. Los requisitos sobre
vfork impuestos
por los estándares son más débiles que aquellos impuestos sobre
fork, por lo que una implementación el la que las dos sean
sinónimas es correcta. En particular, el programador no puede confiar en
que el padre se quede bloqueado hasta una llamada a
execve() o
_exit() y no puede confiar en ningún comportamiento
específico en relación a la memoria compartida.
VÉASE TAMBIÉN¶
clone(2),
execve(2),
fork(2),
wait(2)