next up previous
Next: Observações relativas aos processos Up: A primitiva fork() Previous: Problema com os buffers


A primitiva wait()

       #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:

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



Subsections
next up previous
Next: Observações relativas aos processos Up: A primitiva fork() Previous: Problema com os buffers
Celso Alberto Saibel Santos 2000-11-14