Answers:
kill -STOP $PID
[...]
kill -CONT $PID
@jordanm补充:还请注意,像SIGKILL(kill -9
)一样,不能忽略SIGSTOP 。
(还可以回答重复/关闭的问题,如何暂停或冻结正在运行的进程?询问在恢复后应用程序崩溃时该怎么办。)
在kill -STOP $PID
&之后,某些过程无法正常恢复kill -CONT $PID
。如果是这种情况,您可以尝试使用CRIU进行检查点/还原。如果您不介意开销,则还可以在虚拟机中运行该过程,您可以将其挂起。
进程在SIGSTOP / SIGCONT之后无法恢复的原因之一可能是,在进程停止并随后通过SIGCONT恢复时,Linux上的某些阻塞系统调用因EINTR而失败。从信号(7):
停止信号中断系统调用和库功能
在Linux上,即使在没有信号处理程序的情况下,某些进程的阻塞接口也可能在进程被停止信号之一停止然后通过SIGCONT恢复后,由于错误EINTR而失败。此行为不受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。
要按名称挂起进程:
pkill --signal STOP ProcessNameToSuspend
要唤醒该过程,请执行以下操作:
pkill --signal CONT ProcessNameToSuspend