Приостановить процесс, не убивая его

11

Итак, у меня есть постоянная программа, работающая в фоновом режиме. Убив его, он просто перезапускается с другим PID. Я хотел бы приостановить это (уложить это спать, фактически не убивая это). Это делает kill -9? Если нет, то как это сделать?

kovach.j
источник

Ответы:

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

@jordanm добавляет: Кроме того, обратите внимание , что , как SIGKILL ( kill -9), SIGSTOP может не быть проигнорирован.

Хауке Лагинг
источник
4

(Также, чтобы ответить на дублированный / закрытый вопрос Как я могу приостановить или заморозить запущенный процесс?, Спрашивая , что делать, если приложения аварийно завершают работу после возобновления работы.)

Есть процессы, которые не возобновляются должным образом после kill -STOP $PID& kill -CONT $PID. Если это так, вы можете попробовать контрольно-пропускной пункт / восстановление с CRIU . Если вы не возражаете против накладных расходов, вы также можете запустить процесс на виртуальной машине, которую вы можете приостановить.

Одна из причин, по которой процесс не возобновляется после SIGSTOP / SIGCONT, может заключаться в том, что некоторые блокирующие системные вызовы в Linux завершаются с ошибкой EINTR, когда процесс останавливается, а затем возобновляется через SIGCONT. Из сигнала (7) :

Прерывание системных вызовов и функций библиотеки сигналами остановки

В Linux даже при отсутствии обработчиков сигналов некоторые блокирующие интерфейсы могут завершиться с ошибкой EINTR после того, как процесс остановлен одним из сигналов остановки, а затем возобновлен через SIGCONT. Это поведение не разрешено POSIX.1 и не встречается в других системах.

[...]

Один из задействованных системных вызовов - epoll_wait (2) . Пример:

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

Скомпилируйте и запустите:

$ gcc -o example example.c
$ echo 'input' | ./example
Received input
$ ./example
Ctrl+Z
[1]+  Stopped                 ./example
$ fg
./example
epoll_wait: Interrupted system call
Питер
источник
Интересный. Можете ли вы привести какие-либо примеры, пожалуйста?
Roaima
> и затем возобновляется через SIGCONT <он говорит, что системный вызов получает EINTRпри SIGCONTотправке в остановленный процесс. Программа остается остановленной, пока SIGCONTне отправлено
myaut
0

Вы можете использовать pkill для отправки STOPи CONTсигналов процесса названий, так что вам не нужно , чтобы узнать PID.

Чтобы приостановить процесс по имени:

 pkill --signal STOP ProcessNameToSuspend

Чтобы восстановить этот процесс:

 pkill --signal CONT ProcessNameToSuspend
Алекс Страгиес
источник