Suspender el proceso sin matarlo

11

Así que tengo un programa persistente ejecutándose en segundo plano. Matarlo solo hace que se reinicie con un PID diferente. Me gustaría suspenderlo (ponerlo a dormir sin matarlo). ¿Kill -9 hace esto? Si no, ¿cómo se debe hacer esto?

kovach.j
fuente

Respuestas:

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

@jordanm agrega: también tenga en cuenta que, al igual que SIGKILL ( kill -9), SIGSTOP no se puede ignorar.

Hauke ​​Laging
fuente
4

(También para responder preguntas duplicadas / cerradas ¿ Cómo puedo pausar o congelar un proceso en ejecución ? , preguntando qué hacer cuando las aplicaciones se bloquean después de reanudar).

Hay procesos que no se reanudan correctamente después de kill -STOP $PID& kill -CONT $PID. Si ese es el caso, puede intentar el punto de control / restauración con CRIU . Si no le importa la sobrecarga, también puede ejecutar el proceso en una máquina virtual, que puede suspender.

Una razón por la cual un proceso no se reanuda después de SIGSTOP / SIGCONT podría ser que algunas llamadas del sistema de bloqueo en Linux fallan con EINTR cuando el proceso se detiene y luego se reanuda a través de SIGCONT. De la señal (7) :

Interrupción de llamadas al sistema y funciones de la biblioteca por señales de parada

En Linux, incluso en ausencia de manejadores de señal, ciertas interfaces de bloqueo pueden fallar con el error EINTR después de que el proceso es detenido por una de las señales de parada y luego se reanuda a través de SIGCONT. POSIX.1 no sanciona este comportamiento y no se produce en otros sistemas.

[...]

Una de las llamadas al sistema afectadas es epoll_wait (2) . Ejemplo:

#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;
}

Compilar y ejecutar:

$ gcc -o example example.c
$ echo 'input' | ./example
Received input
$ ./example
Ctrl+Z
[1]+  Stopped                 ./example
$ fg
./example
epoll_wait: Interrupted system call
Peter
fuente
Interesante. ¿Puede proporcionar algún ejemplo, por favor?
roaima
> y luego se reanuda a través de SIGCONT <dice que la llamada del sistema se recibe EINTRcuando se SIGCONTenvía al proceso detenido. Los restos programa dejó hasta que SIGCONTse envía
myaut
0

Puede usar pkill para enviar las señales STOPy CONTa los nombres de proceso, de modo que no necesite averiguar el PID.

Para suspender un proceso por nombre:

 pkill --signal STOP ProcessNameToSuspend

Para reactivar ese proceso:

 pkill --signal CONT ProcessNameToSuspend
Alex Stragies
fuente