Suspender o processo sem matá-lo

11

Então, eu tenho um programa persistente em execução em segundo plano. Matá-lo apenas faz com que seja reiniciado com um PID diferente. Eu gostaria de suspendê-lo (colocá-lo para dormir sem realmente matá-lo). Kill -9 faz isso? Caso contrário, como isso deve ser feito?

kovach.j
fonte

Respostas:

14
kill -STOP $PID
[...]
kill -CONT $PID

@ Jordanm acrescenta: Observe também que, como SIGKILL ( kill -9), SIGSTOP não pode ser ignorado.

Hauke ​​Laging
fonte
4

(Também para responder a uma pergunta duplicada / fechada Como posso pausar ou congelar um processo em execução?, Perguntando sobre o que fazer quando os aplicativos falham após a retomada.)

Existem processos que não são retomados corretamente após kill -STOP $PID& kill -CONT $PID. Se for esse o caso, você pode tentar o ponto de verificação / restauração com o CRIU . Se você não se importa com a sobrecarga, também pode executar o processo em uma máquina virtual, que pode ser suspensa.

Uma razão pela qual um processo não é retomado após o SIGSTOP / SIGCONT pode ser que algumas chamadas do sistema de bloqueio no Linux falhem com o EINTR quando o processo é parado e, em seguida, retomado pelo SIGCONT. Do sinal (7) :

Interrupção de chamadas do sistema e funções da biblioteca por sinais de parada

No Linux, mesmo na ausência de manipuladores de sinal, certas interfaces de bloqueio podem falhar com o erro EINTR após o processo ser parado por um dos sinais de parada e, em seguida, retomado via SIGCONT. Esse comportamento não é sancionado pelo POSIX.1 e não ocorre em outros sistemas.

[...]

Uma das chamadas de sistema afetadas é epoll_wait (2) . Exemplo:

#include <stdio.h>
#include <stdlib.h>
#include <memory.h>
#include <sys/epoll.h>

int
main(int argc, char *argv[])
{
    int fd = 0;

    int efd = epoll_create(1);
    if (efd == -1) {
        perror("epoll_create");
        exit(1);
    }

    struct epoll_event ev;
    memset(&ev, 0, sizeof(ev));
    ev.events = EPOLLIN;
    ev.data.fd = fd;

    if (epoll_ctl(efd, EPOLL_CTL_ADD, fd, &ev) == -1) {
        perror("epoll_ctl");
        exit(1);
    }

    int res = epoll_wait(efd, &ev, 1, -1);
    if (res == -1) {
        perror("epoll_wait");
        exit(1);
    }

    if (ev.events & EPOLLIN && ev.data.fd == fd) {
        printf("Received input\n");
    }

    return 0;
}

Compile e execute:

$ gcc -o example example.c
$ echo 'input' | ./example
Received input
$ ./example
Ctrl+Z
[1]+  Stopped                 ./example
$ fg
./example
epoll_wait: Interrupted system call
Pedro
fonte
Interessante. Você pode fornecer alguns exemplos, por favor?
roaima 18/03/16
> e, em seguida, retomado via SIGCONT <indica que a chamada do sistema é recebida EINTRquando SIGCONTenviada para o processo parado. O programa permanece parado até SIGCONTser enviado
myaut 18/03/16
0

Você pode usar o pkill para enviar os sinais STOPe CONTpara nomes de processos, para que você não precise descobrir o PID.

Para suspender um processo pelo nome:

 pkill --signal STOP ProcessNameToSuspend

Para ativar esse processo de backup:

 pkill --signal CONT ProcessNameToSuspend
Alex Stragies
fonte