Perl fork and kill - kill(0, $pid) 总是返回 1,并且不能杀死孩子 [英] Perl fork and kill - kill(0, $pid) always returns 1, and can't kill the child
问题描述
我正在 Linux 主机上运行 perl 脚本.我正在尝试编写一个分叉脚本,其中孩子启动一个需要永远的程序,而父母在 5 秒后超时,杀死孩子.这是我所拥有的:
I am running a perl script on a Linux host. I'm trying to write a script that forks, where the child starts a program that takes forever and the parent times out after 5 seconds, killing the child. Here is what I have:
my $start = time();
my $timeOut = 5;
my $childPid = fork();
if ($childPid) {
# I am the parent, and $childPid is my child
while (kill(0, $childPid)) {
if (time() > $start + $timeOut) {
$numKilled = kill(SIGTERM, $childPid);
printf("numKilled: %s\n", $numKilled);
}
sleep 1;
}
}
else {
# I am the child - do something that blocks forever
`adb -s 410bf6c1 logcat`;
exit;
}
输出:
aschirma@graphics9-lnx:~$ perl perl-fork-test.pl
numKilled: 1
numKilled: 1
numKilled: 1
numKilled: 1
numKilled: 1
...
我期望的行为是我只看到numKilled: 1"一次,并且子进程(及其任何子进程)在大约 5 秒后被杀死.但我从实验中看到,无论是孩子还是他的孩子都没有被杀死.kill(SIGTERM, $childPid)
似乎什么都不做.
The behavior I expect is that I see "numKilled: 1" exactly once, and the child process (and any of its children) is killed after roughly 5 seconds. But I see from experiment that neither the child nor its children are getting killed. The kill(SIGTERM, $childPid)
appears to do nothing.
我怎样才能真正杀死孩子?
How can I actually kill the child?
推荐答案
来自 perldoc 分支:
如果你分叉而不等待你的孩子,你会积累僵尸.在某些系统上,您可以通过将 $SIG{CHLD} 设置为忽略".
If you fork without ever waiting on your children, you will accumulate zombies. On some systems, you can avoid this by setting $SIG{CHLD} to "IGNORE" .
将 $SIG{CHLD} = 'IGNORE';
添加到代码顶部时,我能够获得所需的行为.
I was able to get the desired behavior when adding $SIG{CHLD} = 'IGNORE';
to the top of your code.
[ben@imac ~]$ perl test.pl
numKilled: 1
[ben@imac ~]$
或者,在 kill
之后添加 waitpid($childPid, 0);
也能解决问题.
Alternatively, adding waitpid($childPid, 0);
after kill
did the trick as well.
这篇关于Perl fork and kill - kill(0, $pid) 总是返回 1,并且不能杀死孩子的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!