【问题标题】:Kill all the child processes when parent is killed杀死父进程时杀死所有子进程
【发布时间】:2015-06-16 13:31:03
【问题描述】:

我在 LINUX 下运行 C++ 程序。
从我的程序代码中,我使用system() 调用另一个程序:

system("calledProgram opt1 opt2 ... opt_n");

但是这个calledProgram 与多个进程一起运行(具有特定名称,例如p1p2p3p4)。

当我的程序被用户从外部杀死时,如何找到并杀死这些进程。

这里 (How to kill process in c++, knowing only part of its name) 描述了如何找到具有特定名称的进程并杀死它们。
但是,如果用户从不同的目录使用相同的选项运行程序会怎样。我是否也应该检查运行目录以找到正确的进程?

还有其他(更好的)方法可以杀死这些子进程吗?

PS:当我从 cmd 行运行calledProgram,然后通过 ctrl+c 杀死它时,它的进程不会被自动杀死。

【问题讨论】:

  • 查看这个答案 - *.com/questions/392022/…。也许,您可以使用其中列出的解决方案之一来终止程序的信号处理程序?

标签: c++ linux process


【解决方案1】:

我建议您使用 fork/exec 而不是 system() 来调用您的新程序。这很简单。请参阅 this

这对您的应用程序来说似乎是必要的,因为您需要“被调用的程序”成为您程序的子程序,这样当有人杀死您的程序时它就会死掉。

您还需要处理 SIGINT 信号。以最简单的方式,您需要这样的东西:

#include<signal.h>

void signal_handler() 
{
    kill(0,SIGTERM);
}

int main() 
{    
    signal(SIGINT,signal_handler);  
}

【讨论】:

  • 这是真的,但它并没有扩展到杀死 shell 的孩子。
【解决方案2】:

杀死一个进程时,所有子进程都会被杀死。 这适用于尚未分离的子进程。

您的进程只需要记住它最近的孩子的 pid 并杀死它们。子进程的子进程会自动死亡。

如果将所有子进程放在同一个进程组中,则可以通过一次 kill(2) 调用杀死所有子进程。

参见:man 2 kill

【讨论】:

  • 这不是真的;杀死一个进程不会自动杀死所有子进程。通常,如果人们看到看起来正在发生的行为,那是由于孩子在 FIFO 上有一个句柄,而他们的父母持有另一边;或具有信号处理程序的父级在退出时关闭其子级;或类似的。