perl - 在退出之前终止 Perl 中的子进程的正确方法是什么?

标签 perl fork irc poe

我正在运行一个 IRC 机器人 ( 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: !!! 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.

What else can I do to kill child processes? The forked process is created using the forkit method in Bot::BasicBot.

Sample script:

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"; }
}

最佳答案

我对你提到的任何模块都不熟悉,但是当我过去编写派生 Perl 程序时,通常只需将此行放在主父进程中就足够了:

$SIG{CHLD} = sub { wait };

这样,当子进程退出并且父进程收到 SIGCHLD 信号时,它会自动通过 wait 获取子进程。

关于perl - 在退出之前终止 Perl 中的子进程的正确方法是什么?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/2487829/

相关文章:

html - 如何使用Perl基于值的刻度为HTML形状创建颜色渐变

python - 散列多个文件

Python IRC 机器人和编码问题

xml - 如何使用 XML :Perl 将子元素添加到 XML 中的节点

c - 如果执行任务失败,如何向多个子进程发送终止信号?

c - Select() 仍然阻止从管道读取

c++ - RPC:永不消亡的子进程

python - 是否可以在类中线程化子类?

java - 当包含反斜杠时,从用户输入创建正则表达式模式不起作用

regex - 如何在 perl 中打印特定格式的数组?