【发布时间】:2009-11-04 18:29:41
【问题描述】:
这是我的代码,为清楚起见删除了错误处理和其他内容:
sub launch_and_monitor {
my ($script, $timeout) = @_;
sub REAPER {
while ((my $child = waitpid(-1, &WNOHANG)) > 0) {}
$SIG{CHLD} = \&REAPER;
}
$SIG{CHLD} = \&REAPER;
my $pid = fork;
if (defined $pid) {
if ($pid == 0) {
# in child
monitor($timeout);
}
else {
launch($script);
}
}
}
启动子执行一个 shell 脚本,该脚本反过来启动其他进程,如下所示:
sub launch($) {
my ($script) = @_;
my $pid = open(PIPE, "$script|");
# write pid to pidfile
if ($pid != 0) {
while(<PIPE>) {
# do stuff with output
}
close(PIPE) or die $!;
}
}
monitor sub基本上只是等待一段指定的时间,然后尝试杀死shell脚本。
sub monitor($) {
my ($timeout) = @_;
sleep $timeout;
# check if script is still running and if so get pid from pidfile
if (...) {
my $pid = getpid(...);
kill 9, $pid;
}
}
这会杀死脚本,但是,它不会杀死它的任何子进程。如何解决?
【问题讨论】:
-
我没有你的主要问题的答案,但我建议将
REAPER设为匿名子,例如my $reaper = sub { ... }; $SIG{CHLD} = $reaper;将命名的 sub 放入另一个 sub 并不会将其隐藏在其他范围内。在 Perl 中,所有命名的 subs 都是包符号 -
好点,感谢您指出这一点