我正在运行一个 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);
}
它有效,但我收到此警告:
14045:!!!子进程 PID:14047 收割: 14045:!!!子进程 PID:14048 收割: 14045:!!!您的程序可能没有使用 sig_child() 来获取进程。 14045:!!!在极端情况下,您的程序可以强制系统重启 14045:!!!如果不纠正这种资源泄漏。
我还能做些什么来杀死子进程?分叉进程是使用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"; }
}