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)