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

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

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

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

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

Есть процессы, которые не kill -STOP $PID должным образом после kill -STOP $PID & kill -CONT $PID . Если это так, вы можете попробовать checkpoint / restore с 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 

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

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

  pkill --signal STOP ProcessNameToSuspend 

Чтобы разбудить этот процесс, выполните следующие действия:

  pkill --signal CONT ProcessNameToSuspend