在退出之前,在perl中杀死子进程的正确方法是什么?

rar*_*box 5 irc perl fork poe

我正在运行一个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)

Eth*_*her 0

我会担心为什么你的子进程没有正确终止。在“正常”情况下,家长不必做任何事情(waitpid如果您关心结果,可以打电话,或者停止处理直到完成)。

这还不是一个真正的答案——您可能必须将一些代码粘贴到子级中。但有一点建议——从fork手动调用的简单程序开始,而不是依赖 CPAN 模块来为您执行此操作。了解系统如何处理多个进程非常重要。然后,当您掌握了这些之后,您就可以利用某些框架来为您处理许多流程。

如果您最近没有阅读过perldoc perlfork ,那么您可能还应该阅读它,并尝试一些示例。