Итак, у меня есть постоянная программа, работающая в фоновом режиме. Убив его, он просто перезапускается с другим PID. Я хотел бы приостановить это (уложить это спать, фактически не убивая это). Это делает kill -9? Если нет, то как это сделать?
kill -STOP $PID
[...]
kill -CONT $PID
@jordanm добавляет: Кроме того, обратите внимание , что , как SIGKILL ( kill -9
), SIGSTOP может не быть проигнорирован.
(Также, чтобы ответить на дублированный / закрытый вопрос Как я могу приостановить или заморозить запущенный процесс?, Спрашивая , что делать, если приложения аварийно завершают работу после возобновления работы.)
Есть процессы, которые не возобновляются должным образом после 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
EINTR
приSIGCONT
отправке в остановленный процесс. Программа остается остановленной, покаSIGCONT
не отправленоВы можете использовать pkill для отправки
STOP
иCONT
сигналов процесса названий, так что вам не нужно , чтобы узнать PID.Чтобы приостановить процесс по имени:
Чтобы восстановить этот процесс:
источник