Exemplo:
/* arquivo test_defunct.c */ #include <errno.h> #include <signal.h> #include <stdio.h> #include <unistd.h> int main() { int pid ; printf("Eu sou %d e eu vou criar um filho\n",getpid()) ; printf("Vou em bloquear em seguida num loop infinito\n") ; pid = fork() ; if(pid == -1) /* erro */ { perror("E impossivel criar um filho") ; exit(-1) ; } else if(pid == 0) /* filho */ { printf("Eu sou %d o filho e estou vivo\n",getpid()) ; sleep(10) ; printf("Vou me suicidar para manter minha consciencia tranquila\n") ; exit(0) ; } else /* pai */ { for(;;) ; /* pai bloqueado em loop infinito */ } }
Resultado da execução:
Lançando a execução em background, tem-se o seguinte resultado:
euler:~/> test_defunct & Vou em bloquear em seguida num loop infinito Eu sou 29733 o filho e estou vivo euler:~/>
Fazendo-se um ps, obtém-se:
euler:~/> ps PID TTY STAT TIME COMMAND 28300 ? S 0:02 -tcsh 29732 ? R 0:01 test_defunct 29733 ? S 0:00 test_defunct 29753 ? R 0:00 ps
Após os 10 segundos, o processo filho anuncia sua morte na tela:
Vou me suicidar para manter minha consciencia tranquila
Refazendo-se um ps, obtém-se:
euler:~/> ps PID TTY STAT TIME COMMAND 28300 ? S 0:02 -tcsh 29732 ? R 1:35 test_defunct 29733 ? Z 0:00 (test_defunct <zombie>) 29735 ? R 0:00 ps
Tente matar o processo filho usando a primitiva kill:
euler:~/> kill -INT 29733 euler:~/> ps PID TTY STAT TIME COMMAND 28300 ? S 0:02 -tcsh 29732 ? R 2:17 test_defunct 29733 ? Z 0:00 (test_defunct <zombie>) 29736 ? R 0:00 ps
Não funciona, não é mesmo! Óbvio, ele é um zumbi!!! Note o resultado do ps para se certificar. Tente agora matar o pai.
euler:~/> kill -INT 29732 [1] Interrupt test_defunct euler:~/>ps PID TTY STAT TIME COMMAND 28300 ? S 0:02 -tcsh 29750 ? R 0:00 ps
Finalmente o processo pai, junto com seu filho zumbi foram finalizados.