#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).