所以我有一个在后台运行的持久程序。杀死它只会导致它以不同的 PID 重新启动。我想暂停它(让它进入睡眠状态而不真正杀死它)。杀-9可以做到这一点吗?如果不是,应该怎么做?
答案1
kill -STOP $PID
[...]
kill -CONT $PID
@乔丹补充:另请注意,like SIGKILL
(与kill -9
)相同并且SIGSTOP
可以不是被忽略。
答案2
(还要回答重复/封闭的问题如何暂停或冻结正在运行的进程?,询问应用程序恢复后崩溃时该怎么办。)
kill -STOP $PID
有些进程在&之后无法正确恢复kill -CONT $PID
。如果是这种情况,您可以尝试检查点/恢复CRIU。如果您不介意开销,您还可以在虚拟机中运行该进程,并且可以将其挂起。
SIGSTOP
进程在/之后无法恢复的原因之一SIGCONT
可能是,EINTR
当进程停止然后通过 恢复时, Linux 上的某些阻塞系统调用会失败SIGCONT
。从信号(7):
通过停止信号中断系统调用和库函数
在 Linux 上,即使没有信号处理程序,在进程被停止信号之一停止然后通过 SIGCONT 恢复后,某些阻塞接口也可能会失败并出现错误 EINTR。此行为不受 POSIX.1 认可,并且不会发生在其他系统上。
[...]
受影响的系统调用之一是epoll_等待(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