kill -STOP $PID
[...]
kill -CONT $PID
@jordanm acrescenta: Observe também que, como SIGKILL ( kill -9
), SIGSTOP pode não ser ignorado.
Portanto, tenho um programa persistente em execução em segundo plano. Matar apenas faz com que ele reinicie com um PID diferente. Eu gostaria de suspendê-lo (colocá-lo para dormir sem realmente matá-lo). Matar -9 faz isso? Se não, como isso deve ser feito?
kill -STOP $PID
[...]
kill -CONT $PID
@jordanm acrescenta: Observe também que, como SIGKILL ( kill -9
), SIGSTOP pode não ser ignorado.
(Também para responder à pergunta duplicada / fechada Como posso pausar ou congelar um processo em execução? , perguntando sobre o que fazer quando os aplicativos falham após o reinício.
Existem processos que não são retomados corretamente após kill -STOP $PID
& %código%. Se for esse o caso, você pode tentar o ponto de verificação / restauração com CRIU . Se você não se importar com a sobrecarga, também poderá executar o processo em uma máquina virtual, que pode ser suspensa.
Um motivo pelo qual um processo não é retomado após o SIGSTOP / SIGCONT pode ser que algumas chamadas do sistema de bloqueio no Linux falhem com o EINTR quando o processo é interrompido e depois reiniciado via SIGCONT. De signal (7) :
Interruption of system calls and library functions by stop signals
On Linux, even in the absence of signal handlers, certain blocking interfaces can fail with the error EINTR after the process is stopped by one of the stop signals and then resumed via SIGCONT. This behavior is not sanctioned by POSIX.1, and doesn't occur on other systems.
[...]
Uma das chamadas do sistema afetadas é epoll_wait (2) . Exemplo:
#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;
}
Compile e execute:
$ gcc -o example example.c
$ echo 'input' | ./example
Received input
$ ./example
Ctrl+Z
[1]+ Stopped ./example
$ fg
./example
epoll_wait: Interrupted system call
Você pode usar pkill para enviar os sinais STOP
e CONT
para nomes de processos, para que você não precisa descobrir o PID.
Para suspender um processo pelo nome:
pkill --signal STOP ProcessNameToSuspend
Para reativar o processo:
pkill --signal CONT ProcessNameToSuspend