Zawieś proces bez jego zabijania

11

Mam więc program działający w tle. Zabicie go powoduje tylko, że uruchomi się ponownie z innym PID. Chciałbym go zawiesić (uśpić, nie zabijając go). Czy to robi kill -9? Jeśli nie, jak należy to zrobić?

kovach.j
źródło

Odpowiedzi:

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

@jordanm dodaje: Należy również pamiętać, że podobnie jak SIGKILL ( kill -9), SIGSTOP nie można zignorować.

Hauke ​​Laging
źródło
4

(Również, aby odpowiedzieć na pytanie powielone / zamknięte. Jak mogę zatrzymać lub zawiesić uruchomiony proces?, Pytając o to, co zrobić, gdy aplikacje ulegną awarii po wznowieniu.)

Istnieją procesy, które nie są wznawiane poprawnie po kill -STOP $PID& kill -CONT $PID. W takim przypadku możesz spróbować sprawdzić / przywrócić za pomocą CRIU . Jeśli nie przeszkadza ci narzut, możesz również uruchomić proces na maszynie wirtualnej, którą możesz zawiesić.

Jednym z powodów, dla których proces nie jest wznawiany po SIGSTOP / SIGCONT, może być to, że niektóre blokujące wywołania systemowe w Linuksie nie działają z EINTR, gdy proces jest zatrzymywany, a następnie wznawiany przez SIGCONT. Z sygnału (7) :

Przerwanie wywołań systemowych i funkcji bibliotecznych przez sygnały stop

W systemie Linux, nawet przy braku programów obsługi sygnałów, niektóre interfejsy blokujące mogą zawieść z błędem EINTR po zatrzymaniu procesu przez jeden z sygnałów zatrzymania, a następnie wznowieniu za pośrednictwem SIGCONT. To zachowanie nie jest sankcjonowane przez POSIX.1 i nie występuje w innych systemach.

[...]

Jednym z wywoływanych wywołań systemowych jest epoll_wait (2) . Przykład:

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

Skompiluj i uruchom:

$ gcc -o example example.c
$ echo 'input' | ./example
Received input
$ ./example
Ctrl+Z
[1]+  Stopped                 ./example
$ fg
./example
epoll_wait: Interrupted system call
Piotr
źródło
Ciekawy. Czy możesz podać jakieś przykłady?
roaima,
>, a następnie wznowione przez SIGCONT <informuje, że wywołanie systemowe jest odbierane EINTRpo SIGCONTwysłaniu do zatrzymanego procesu. Program pozostaje zatrzymany, dopóki nie SIGCONTzostanie wysłany
myaut
0

Możesz użyć pkill, aby wysłać sygnały STOPi CONTdo nazw procesów, abyś nie musiał szukać PID.

Aby zawiesić proces według nazwy:

 pkill --signal STOP ProcessNameToSuspend

Aby obudzić ten proces z powrotem:

 pkill --signal CONT ProcessNameToSuspend
Alex Stragies
źródło