Como matar todos os processos filhos após o processo pai ter morrido e todos eles terem passado para o init?

1

Eu tenho o seguinte problema: quando meu processo pai grande morre (acidentalmente!) depois que ele criou muitos processos filhos, todos os processos filhos mudaram para init .

Como posso matar com segurança todos esses processos filhos?

Eu pensei que há uma maneira: conheça o processo pai através deste comando

ps -o ppid= <number of some child process>

e depois de fazer isso eu posso usar esta resposta e matar todos os processos filhos.

O problema aqui é que todos os processos da criança mudaram para init e esta solução não funciona ...

Existe uma maneira, exceto para htop e matar tudo manualmente?

Obrigado antecipadamente!

    
por Ivan 09.11.2017 / 15:23

2 respostas

2
  1. Solução alternativa de curto prazo: Se o seu processo pai grande criar todas as crianças ao mesmo tempo, classifique a saída de ps por STIME (hora de início do processo). Isso (junto com o nome do processo) irá ajudá-lo a identificar os órfãos desta invocação.
  2. Correção de longo prazo: Modifique seu programa de processo pai grande para manter um log dos PIDs de todos os processos que inicia. Então você pode usar isso como uma lista de mortes.
por 09.11.2017 / 15:53
1

Não é portável, mas o Linux permite não- init de reparos de processos, veja PR_SET_CHILD_SUBREAPER em prctl (2) .

PR_SET_CHILD_SUBREAPER (since Linux 3.4)

      If arg2 is nonzero, set the "child subreaper" attribute of the calling process; if arg2 is zero, unset the attribute.  When a process is marked as a child subreaper, all of the children that it creates, and their descendants, will be marked as having a subreaper.  In effect, a subreaper fulfills the role of init(1) for its descendant processes.  …

No entanto, seu subperme também pode morrer (acidentalmente). Outra opção, novamente no Linux, pode ser um namespace ou contêiner PID. A solução mais comum é tornar o processo pai o mais simples e robusto possível, de modo que seja menos provável que ele seja expulso ou morra.

Mais complicado seria vincular os processos filhos ao pai, embora isso não seja possível se o filho processar algo do executivo ou se os processos filhos não puderem ser complicados com E / S assíncrona, pois a criança terá que verificar o pipe para que o EOF perceba que o pai foi embora:

#include <err.h>
#include <errno.h>
#include <unistd.h>

int main(void)
{
    int fd[2];
    char ch;
    ssize_t ret;
    pipe(fd);

    switch (fork()) {
    case -1:
        err(1, "fork failed");
    case 0:
        close(fd[1]);
        warnx("child  %d start", getpid());
        /* this would really need to be done in an event loop so the
         * child can do other things meanwhile */
        ret = read(fd[0], &ch, 1);
        if (ret == 0)
            errx(1, "EOF from parent (child %d)", getpid());
        break;
    default:
        /* and another child process... */
        switch (fork()) {
        case -1:
            err(1, "fork failed");
        case 0:
            close(fd[1]);
            warnx("child  %d start", getpid());
            ret = read(fd[0], &ch, 1);
            if (ret == 0)
                errx(1, "EOF from parent (child %d)", getpid());
            break;
        default:
            sleep(9);
        }
    }
    return 0;
}
    
por 09.11.2017 / 16:07

Tags