挂起进程而不杀死它

挂起进程而不杀死它

所以我有一个在后台运行的持久程序。杀死它只会导致它以不同的 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

答案3

您可以使用删除发送STOPCONT 向进程名称发出信号,这样您就不需要找出 PID。

按名称暂停进程:

 pkill --signal STOP ProcessNameToSuspend

要唤醒该进程:

 pkill --signal CONT ProcessNameToSuspend

在标准系统上,您可以使用TAB-completionProcessName以及所有其他命令元素。

相关内容