我正在运行一个IRC Bot(Bot :: BasicBot),它有两个运行File :: Tail的子进程但是在退出时它们不会终止.所以我在退出前使用这样的Proc :: ProcessTable来杀死它们:
my $parent=$$;
my $proc_table=Proc::ProcessTable->new();
for my $proc (@{$proc_table->table()}) {
kill(15, $proc->pid) if ($proc->ppid == $parent);
}
Run Code Online (Sandbox Code Playgroud)
它有效但我得到这个警告:
14045: !!! Child process PID:14047 reaped: 14045: !!! Child process PID:14048 reaped: 14045: !!! Your program may not be using sig_child() to reap processes. 14045: !!! In extreme cases, your program can force a system reboot 14045: !!! if this resource leakage is not corrected.
我还能做些什么来杀死子进程?分叉进程是使用Bot :: BasicBot中的forkit方法创建的.
示例脚本:
package main;
my $bot = SOMEBOT->new ( server => 'irc.dal.net', channels => ['#anemptychannel'] );
$SIG{'INT'} = 'Handler';
$SIG{'TERM'} = 'Handler';
sub Handler {
$bot->_stop('Leaving.');
}
$bot->run;
package SOMEBOT;
use base qw(Bot::BasicBot);
use File::Tail;
use Proc::ProcessTable;
sub irc_error_state { die if $_[10] =~ /Leaving\./; }
sub help { return; }
sub stop_state {
my $parent=$$;
my $proc_table=Proc::ProcessTable->new();
for my $proc (@{$proc_table->table()}) {
kill(15, $proc->pid) if ($proc->ppid == $parent);
}
die;
}
sub connected {
my $self = shift;
$self->forkit (
run => \&announcer,
body => '/home/somebody/somefile.txt',
channel => '#anemptychannel',
) unless $self->{log1};
$self->{log1} = 1;
$self->forkit (
run => \&announcer,
body => '/home/somebody/anotherfile.txt',
channel => '#anemptychannel',
) unless $self->{log2};
$self->{log2} = 1;
}
sub announcer {
my $announcefile = shift;
my $file=File::Tail->new(name => $announcefile, maxinterval=>5, adjustafter=>7);
while (defined(my $line=$file->read)) { chomp $line; print "$line\n"; }
}
Run Code Online (Sandbox Code Playgroud)
我会担心为什么你的子进程没有正确终止。在“正常”情况下,家长不必做任何事情(waitpid如果您关心结果,可以打电话,或者停止处理直到完成)。
这还不是一个真正的答案——您可能必须将一些代码粘贴到子级中。但有一点建议——从fork手动调用的简单程序开始,而不是依赖 CPAN 模块来为您执行此操作。了解系统如何处理多个进程非常重要。然后,当您掌握了这些之后,您就可以利用某些框架来为您处理许多流程。
如果您最近没有阅读过perldoc perlfork ,那么您可能还应该阅读它,并尝试一些示例。