我是新手。我的程序使用系统调用fork()
在生命周期内创建了一些子进程。我需要处理父级的中断信号,并在其处理程序中终止在程序运行时创建的所有子进程。
我试过以下代码......
setpgrp(0,0);
$SIG{INT} = \&kill_all;
sub kill_all() {
print "Going to kill child processes \n";
kill -9, getpgrp();
}
....
fork()..
....
fork()...
....
fork()
.....
但似乎并非所有进程都被杀死,请建议正确的方法。
答案 0 :(得分:3)
首先 - 不要kill -9
。除非你绝对不得不这样做,这是不好的做法。 <{1}}或SIGTERM
更好。
要将内容发送到您的流程组,最简单的方法是(来自-15
:http://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";
,那么分叉子项也有该处理程序。您可能需要在子进程中再次删除它。