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

时间:2015-03-25 16:11:20

标签: perl parallel-processing fork kill child-process

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

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

但似乎并非所有进程都被杀死,请建议正确的方法。

1 个答案:

答案 0 :(得分:3)

首先 - 不要kill -9。除非你绝对不得不这样做,这是不好的做法。 <{1}}或SIGTERM更好。

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

perlipc

  

将信号发送到负进程ID意味着您将信号发送到整个Unix进程组。

或者 - kill -$$返回一个pid。你可以明确杀死那个pid。

如果您对孩子没有退出以应对杀戮信号的问题,那么最常见的问题是他们已进入不间断状态。

这可能类似于NFS挂载上的IO(或其他IO设备不可用)。不幸的是,这是一个特定于操作系统的问题,它不能通过perl解决。您可以通过运行fork进行检查,然后检查“状态”状态。旗。

ps -e v

或者他们已成为僵尸进程,并等待收获。你可以通过设置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"). 来避免这种情况 但是正如评论中所指出的那样 - 你不应该将这个以及作为fork-pid的杀戮,因为它会产生竞争条件。

您还应该注意 - 如果您配置信号处理程序,然后然后 $SIG{'CHLD'} = "IGNORE";,那么分叉子项也有该处理程序。您可能需要在子进程中再次删除它。