杀死进程本身和所有子进程的最佳方法

Best way to kill process itself and all child processesg

我是新手。我的程序使用系统调用 fork() 在生命周期内创建了一些子进程。我需要处理父进程的中断信号,并在它的处理程序中杀死所有在程序运行时创建的子进程。
我尝试了以下代码...

setpgrp(0,0);
$SIG{INT} = \&kill_all;
sub kill_all() {
     print "Going to kill child processes \n";
     kill -9, getpgrp();
}
....
fork()..
....
fork()...
....
fork()
.....

不过好像不是所有的进程都被kill掉了,请指教正确的方法。

首先 - 不要 kill -9。除非您绝对必须这样做,否则这是不好的做法。 SIGTERM-15 更好。

要将内容发送到您的进程组,最简单的方法是(来自 perlipchttp://perldoc.perl.org/perlipc.html#Signals

kill -$$

Sending a signal to a negative process ID means that you send the signal to the entire Unix process group.

或者 - fork returns 一个 pid。你可以明确地杀死那个 pid。

如果您遇到 children 没有响应终止信号而退出的问题,那么最常见的问题是它们进入了不间断状态。

这可能类似于 NFS 装载上的 IO(或其他不可用的设备 IO)。不幸的是,这是一个 OS 特定问题,无法通过 perl 解决。您可以通过 运行 ps -e v 检查并检查 'state' 标志。

state    The state is given by a sequence of characters, for example, "RWNA". The      first character indicates the run state of the process:
D    Marks a process in disk (or other short term, uninterruptible) wait.
I    Marks a process that is idle (sleeping for longer than about 20 seconds).  
L    Marks a process that is waiting to acquire a lock.
R    Marks a runnable process.
S    Marks a process that is sleeping for less than about 20 seconds.
T    Marks a stopped process.
W    Marks an idle interrupt thread.
Z    Marks a dead process (a "zombie").

或者它们已经成为僵尸进程,正在等待被收割。您可以通过设置 $SIG{'CHLD'} = "IGNORE"; 来避免这种情况 但正如评论中所指出的那样 - 你不应该像 fork-pid 那样 一起杀人,因为它会产生竞争条件。

您还应该注意 - 如果您配置了信号处理程序,并且 然后 fork,那么分叉的 child 也有该处理程序。您可能需要在 child 过程中再次删除它。