Sospendi il processo senza ucciderlo


11

Quindi ho un programma persistente in esecuzione in background. Ucciderlo provoca semplicemente il riavvio con un PID diverso. Vorrei sospenderlo (mettilo a dormire senza ucciderlo). Uccide -9 fa questo? In caso contrario, come dovrebbe essere fatto?

Risposte:


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

@jordanm aggiunge: Nota anche che come SIGKILL ( kill -9), SIGSTOP non può essere ignorato.


4

(Anche per rispondere a una domanda duplicata / chiusa Come posso mettere in pausa o bloccare un processo in esecuzione , chiedendo cosa fare quando le applicazioni si arrestano in modo anomalo dopo il riavvio.)

Ci sono processi che non riprendono correttamente dopo kill -STOP $PID& kill -CONT $PID. In tal caso, puoi provare checkpoint / restore con CRIU . Se non ti dispiace il sovraccarico, puoi anche eseguire il processo in una macchina virtuale, che puoi sospendere.

Uno dei motivi per cui un processo non riprende dopo SIGSTOP / SIGCONT potrebbe essere che alcune chiamate di sistema bloccanti su Linux falliscono con EINTR quando il processo viene interrotto e poi ripreso tramite SIGCONT. Dal segnale (7) :

Interruzione delle chiamate di sistema e delle funzioni di libreria mediante segnali di arresto

Su Linux, anche in assenza di gestori di segnali, alcune interfacce di blocco possono non riuscire con l'errore EINTR dopo che il processo è stato arrestato da uno dei segnali di arresto e quindi ripreso tramite SIGCONT. Questo comportamento non è sanzionato da POSIX.1 e non si verifica su altri sistemi.

[...]

Una delle chiamate di sistema interessate è epoll_wait (2) . Esempio:

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

Compila ed esegui:

$ gcc -o example example.c
$ echo 'input' | ./example
Received input
$ ./example
Ctrl+Z
[1]+  Stopped                 ./example
$ fg
./example
epoll_wait: Interrupted system call

Interessante. Sei in grado di fornire qualche esempio, per favore?
roaima,

> e quindi ripreso tramite SIGCONT <indica che la chiamata di sistema viene inviata EINTRquando viene SIGCONTinviata al processo interrotto. Il programma rimane fermo fino a quando non SIGCONTviene inviato
myaut

0

È possibile utilizzare pkill per inviare i segnali STOPe CONTai nomi dei processi, in modo da non dover scoprire il PID.

Per sospendere un processo per nome:

 pkill --signal STOP ProcessNameToSuspend

Per riattivare il processo di backup:

 pkill --signal CONT ProcessNameToSuspend
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.