Es necesario sincronizar el proceso padre con los procesos hijo. Para ello es posible usar bien la función wait bien la función waitpid :
$ cat -n forkw.pl 1 #!/usr/bin/perl -w 2 use strict; 3 4 print "PID=$$\n"; 5 6 my $child = fork(); 7 die "Falló el fork: $!" unless defined $child; 8 9 if ($child > 0) { # proceso padre 10 print "Aqui proceso padre: PID=$$, hijo=$child\n"; 11 waitpid $child, 0; 12 } else { #proceso hijo 13 my $ppid = getppid(); 14 print "Aqui proceso hijo: PID=$$, padre=$ppid\n"; 15 exit 0; 16 }
La función wait tiene el formato
$pid = wait()La función hace que el proceso espere por la finalización de cualquier hijo y retorna el PID del proceso hijo. El proceso se bloquea hasta que exista un hijo que termine. Se puede consultar el código de terminación examinando la variable especial $? . Un código 0 indica una salida normal.
La función waitpid tiene el formato
$pid = waitpid($pid, $flags)En este caso se espera por el hijo especificado en
$pid
.
Es posible usar un argumento $pid
igual a
para indicar
que se espera por cualquier proceso (a la wait
).
La conducta de waitpid
pude modificarse mediante
el uso del argumento $flags
.
Hay un buen número de constantes definidas en el grupo
:sys_wait_h del módulo estandar POSIX .
Estas constantes se utilizan combinandolas con un OR
binario.
La constante más usada es WNOHANG
la cual hace que el proceso
no se bloquee (útil si se quiere hacer polling ).
La función retorna el PID del proceso o
si no existe ninguno
disponible (cuando se usa la versión sin bloqueo).
Otra constante es WUNTRACED la cual le indica a
waitpid
que además de los hijos que hayan terminado también recolecte
los hijos parados mediante una señal de STOP o TSTP .
En muchos sistemas Unix, una vez que se ha realizado el fork
,
si el proceso padre termina antes que
lo haga el hijo
el proceso hijo no desaparece totalmente sino que queda
en un estado conocido como zombie.
El zombie permanece en la tabla de procesos con el único objeto de entregar su estatus de salida al proceso padre por si este pregunta por el usando wait o waitpid .
Esta forma de trabajo se denomina reaping (segar).
Si el proceso padre se ramifica en un gran número de hijos
y no siega es posible que la tabla de procesos
se llene de procesos zombis. Por tanto, todo programa que llama
a fork
debe segar sus hijos llamando a wait o
waitpid .