#include <sys/types.h>
#include <sys/wait.h>
pid_t wait(int *status) /* espera a morte de um filho */
pid_t waitpid(pid_t pid, int *status, int options)
int *status /* status descrevendo a morte do filho */
Valor de retorno: identificador do processo morto ou -1 em
caso de erro.
A função wait suspende a execução do processo até a morte de seu filho. Se o filho já estiver morto no instante da chamada da primitiva (caso de um processo zumbi, abordado mais a frente), a função retorna imediatamente.
A função waitpid suspende a execução do processo até que o filho especificado pelo argumento pid tenha morrido. Se ele já estiver morto no momento da chamada, o comportamento é idêntico ao descrito anteriormente.
O valor do argumento pid pode ser:
< -1 : significando que o pai espera a morte de qualquer
filho cujo o ID do grupo é igual so valor de pid;
> 0 : significando que o pai espera a morte de um processo filho
com um valor de ID exatamente igual a pid.
Se status é não nulo (NULL), wait e waitpid armazena a informação relativa a razão da morte do processo filho, sendo apontada pelo ponteiro status. Este valor pode ser avaliado com diversas macros que são listadas com o comando shell man 2 wait.
O código de retorno via status indica a morte do processo que pode ser devido uma:
Exemplo:
/* arquivo test_wait1.c */
#include <errno.h>
#include <signal.h>
#include <stdio.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/wait.h>
int main()
{
int pid ;
printf("\nBom dia, eu me apresento. Sou o processo %d.\n",getpid()) ;
printf("Estou sentindo uma coisa crescendo dentro de minha barriga...");
printf("Sera um filho?!?!\n") ;
if (fork() == 0) {
printf("\tOi, eu sou %d, o filho de %d.\n",getpid(),getppid()) ;
sleep(3) ;
printf("\tEu sao tao jovem, e ja me sinto tao fraco!\n") ;
printf("\tAh nao... Chegou minha hora!\n") ;
exit(7) ;
}
else {
int ret1, status1 ;
printf("Vamos esperar que este mal-estar desapareca.\n") ;
ret1 = wait(&status1) ;
if ((status1&255) == 0) {
printf("Valor de retorno do wait(): %d\n",ret1) ;
printf("Parametro de exit(): %d\n",(status1>>8)) ;
printf("Meu filho morreu por causa de um simples exit.\n") ;
}
else
printf("Meu filho nao foi morto por um exit.\n") ;
printf("\nSou eu ainda, o processo %d.", getpid());
printf("\nOh nao, recomecou! Minha barriga esta crescendo
de novo!\n");
if ((pid=fork()) == 0) {
printf("\tAlo, eu sou o processo %d, o segundo filho de %d\n",
getpid(),getppid()) ;
sleep(3) ;
printf("\tEu nao quero seguir o exemplo de meu irmao!\n") ;
printf("\tNao vou morrer jovem e vou ficar num loop infinito!\n") ;
for(;;) ;
}
else {
int ret2, status2, s ;
printf("Este aqui tambem vai ter que morrer.\n") ;
ret2 = wait(&status2) ;
if ((status2&255) == 0) {
printf("O filho nao foi morto por um sinal\n") ;
}
else {
printf("Valor de retorno do wait(): %d\n",ret2) ;
s = status2&255 ;
printf("O sinal assassino que matou meu filho foi: %d\n",s) ;
}
}
}
exit(0);
}
Resultado da execução:
euler:~/> test_wait &
[1] 29079
euler:~/> Bom dia, eu me apresento. Sou o processo 29079.
Estou sentindo uma coisa crescendo dentro de minha barriga...Sera um filho?!?!
Vamos esperar que este mal-estar desapareca.
Oi, eu sou 29080, o filho de 29079.
Eu sao tao jovem, e ja me sinto tao fraco!
Ah nao... Chegou minha hora!
Valor de retorno do wait(): 29080
Parametro de exit(): 7
Meu filho morreu por causa de um simples exit.
Sou eu ainda, o processo 29079.
Oh nao, recomecou! Minha barriga esta crescendo de novo!
Este aqui tambem vai ter que morrer.
Alo, eu sou o processo 29081, o segundo filho de 29079
Eu nao quero seguir o exemplo de meu irmao!
Nao vou morrer jovem e vou ficar num loop infinito!
euler:~/> ps
PID TTY STAT TIME COMMAND
28300 ? S 0:01 -tcsh
29079 ? S 0:00 test_wait
29081 ? R 5:06 test_wait
29103 ? R 0:00 ps
euler:~/> kill -8 29081
euler:~/> Valor de retorno do wait(): 29081
O sinal assassino que matou meu filho foi: 8.
[1] Done test_wait
euler:~/>
O programa é lançado em background e, após o segundo filho estiver
bloqueado num laço infinito, um sina será lançado para interromper sua
execução através do comando shell
kill <numero-do-sinal> <pid-filho2>
Observações:
Após a criação dos filhos, o processo pai ficará bloqueado na espera
de que estes morram. O primeiro filho morre pela chamada de um
exit(), sendo que o parâmetro de wait() irá conter,
no seu byte esquerdo, o parâmetro passado ao exit(); neste
caso, este parâmetro tem valor 7.
O segundo filho morre com a recepção de um sinal, o parâmetro da primitiva wait() irá conter, nos seus 7 primeiros bits, o número do sinal (no exemplo anterior ele vale 8).