【问题标题】:Kill all child processes of a parent but leave the parent alive杀死父进程的所有子进程,但让父进程存活
【发布时间】:2013-08-25 20:52:47
【问题描述】:

杀死父进程而不是父进程的最佳方法是什么?假设我有不确定数量的子进程,我已经派生了一个给定的警报,在我的信号处理程序中,我想杀死我所有的子进程,但由于各种原因让自己继续运行。

到目前为止,我正在使用 kill(-1*parentPid, SIGKILL) 但这会杀死我的父母及其孩子。

【问题讨论】:

  • 你可以在 fork 时简单地在一个简单的数组中跟踪孩子的 PID 吗?
  • 我试过了,但由于不知道要分叉的进程数量,我必须保持一个计数器,以便正确索引它们,并且计数器变量的状态是在多个流程中没有很好地定义......当然,我的实现可能很差。
  • 所以你可以向父母和孩子发送信号,对吧?
  • 李东,这是一个难题,在我当前的实现中,只有父级注册了信号处理程序......哎呀,我不妨发布代码。

标签: c unix process


【解决方案1】:

实现这一点的一种方法是传递一些可以捕获的信号(不是SIGKILL)。然后,安装一个信号处理器,检测当前进程是否为父进程,如果不是父进程则调用_exit()

您可以使用SIGUSR1SIGUSR2,或者SIGQUIT

我已经说明了这种技术here

可选地(如 Lidong 建议的那样),父进程可以在发出kill() 命令之前在信号上使用SIG_IGN

signal(SIGQUIT, SIG_IGN);
kill(0, SIGQUIT);

【讨论】:

    【解决方案2】:

    你可以在fork时为子进程设置一个新的进程组,当你想杀死子进程及其后代时,你可以使用killpg,示例代码如下:

    #include <unistd.h>
    #include <signal.h>
    #include <stdio.h>
    
    void parent(pid_t pid) {
        killpg(pid, SIGKILL);
    }
    
    void child(void) {
        if (-1 == setsid())
            return;
    
        while(1) {
            sleep(1);
            printf("child\n");
        } 
    }
    
    
    int main() {
        pid_t pid;
        switch ((pid=fork())) {
        case 0: // child
            child();
            break;
    
        default: // parent
            getchar();
            getchar();
            parent(pid);
        }
    
        return 0;
    }
    

    【讨论】:

      【解决方案3】:

      Jxh 的回答很好。但是,也许您可​​以在fork 之后为每个子进程提供一个signal hander 并让它调用exit 函数。你给父母一个signal hander,让它ignore信号(比如SIGUSR1)。这可能会添加代码行,但您不需要在信号处理函数中检测进程是父进程还是子进程。

      【讨论】:

      • 你好 Lidong,一个小例子可以很好地说明一个人应该做什么=)