No Linux existem dois tipos de processos que podem ser facilmente confundidos. Eu mesmo já respondi coisa errada quando perguntado sobre um ou outro, então vai aqui uma explicação rápida:

Órfãos:

chaves-triste-580x348

O nome foi muito bem escolhido: O processo pai terminou ou morreu e o processo atual (filho) agora é órfão. No entanto todo processo precisa de um pai, por isso o Linux vai automaticamente fazer com que o processo init adote o processo órfão. Essa operação é  chamada reparenting.

A criação intencional de processos órfãos é normalmente ligada a daemons – processos que rodam em background e não precisam de interação de usuário ou stdin/stdout/stderr.

Normalmente são processos benéficos e desejados e não há com que se preocupar.

Um exemplo simples de como iniciar um daemon seria criar um script como esse:

$ cat test.sh 
#!/bin/bash
echo PID is $$
while true
do
    sleep 1
done

E executá-lo assim:

$ nohup ./test.sh &
[1] 8839
nohup: ignoring input and appending output to ‘nohup.out’

Enquanto o seu terminal estiver rodando o PPID (Parent Process ID) será a sua sessão do shell:

$ tail -1 nohup.out 
PID is 8839
$ ps -p 8839 -o ppid
 PPID
 7470
$ ps auxw|grep 7470
ebastos 7470 0.0 0.1 27952 5108 pts/15 Ss 10:41 0:00 -bash

Mas se você encerrar sua sessão:

$ ps -p 8839 -o ppid
 PPID
 1882
$ ps -auxw|grep 1882
ebastos   1882  0.0  0.0  40172  2536 ?        Ss   07:59   0:00 init --user

 

BOOM!

 

Por outro lado processos órfãos também podem ser criados se o processo pai morre ou é morto sem fazer a limpeza necessária e simplesmente abandona os processos filhos. Nesse caso eles vão continuar rodando e consumindo recursos do sistema, o que geralmente não é bom. Numa situação normal o processo init não deve ter muitos filhos.

Não existe uma forma simples de identificar processos órfãos, exceto examinar todos os filhos do processo init e verificar se eles são legítimos ou não.

Para matar um processo órfão um simples kill (-15 ou -9) resolve.

Zumbis

the_walking_dead_the_complete_first_season_3

Zumbi é quase o oposto de órfão. Quando um processo pai gera um filho ele aguarda a execução desse filho e no encerramento do mesmo (terminated) lê o código de saída (exit code). Quando isso acontece o processo é retirado da tabela de processos (process table) e a vida continua.

No entanto algum bug no código do processo pai pode criar um processo filho mas nunca ler o código de saída do mesmo. Por isso o processo vai estar encerrado (terminated) mas ainda vai constar na tabela de processos.

Um exemplo de como gerar um processo zumbi:

$ cat zumbi.c
#include <stdlib.h>
#include <sys/types.h>
#include <unistd.h>

int main ()
{
  pid_t child_pid;

  child_pid = fork ();
  if (child_pid > 0) {
    sleep (60);
  }
  else {
    exit (0);
  }
  return 0;
}
$ gcc -Wall zumbi.c -o zumbi
$ ./zumbi &
[1] 12929
$ ps -eaf|grep zumbi
ebastos  12929  7452  0 11:34 pts/10   00:00:00 ./zumbi
ebastos  12931 12929  0 11:34 pts/10   00:00:00 [zumbi] <defunct>

O processo pai cria um filho através de um fork(), mas larga ele lá. Esse processo filho então entra num status , onde ele já encerrou a execução e nada foi feito a respeito da saída dele.

Ao contrário de um processo órfão, um processo zumbi não consome recursos do sistema e – normalmente – não causa problemas. Também são bem fáceis de identificar, basta procurar por processos . Ou também com status Z:

USER       PID %CPU %MEM    VSZ   RSS TTY      STAT START   TIME COMMAND
ebastos  14730  0.0  0.0      0     0 pts/10   Z    11:48   0:00 [zumbi] <defunct>

O problema é matar processos zumbis. Como você mata algo que já está morto?

Uma opção – que normalmente não vai funcionar – é descobrir qual o processo pai do zumbi e mandar um SIGCHLD pra ele. (kill -17). Vale tentar, mas não espere muito disso.

A única forma garantida é matar o processo pai. Isso vai fazer com que os processos zumbis virem órfãos, sejam adotados pelo init e esse finalmente vai removê-los da tabela de processos.

 

 

Quem aprendeu alguma coisa hoje?