What is the correct way to kill child processes in perl before exiting?

I run IRC Bot ( Bot :: BasicBot ), which has two child processes that execute File :: Tail , but they do not end when they exit. Therefore, I kill them using Proc :: ProcessTable , as it was before the release:

my $parent=$$;
my $proc_table=Proc::ProcessTable->new();
for my $proc (@{$proc_table->table()}) {
  kill(15, $proc->pid) if ($proc->ppid == $parent);
}

It works, but I get this warning:

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 bifurcation 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"; }
}
+5
source share
4 answers

I am not familiar with any of the modules you mentioned, but when I wrote Perl forking programs in the past, it was usually enough to put this line in the main parent process:

$SIG{CHLD} = sub { wait };

Thus, when the child process ends and the parent process receives the SIGCHLD signal, it automatically picks up the child with wait.

+1
source

0.82, Bot::BasicBot ( forkit()) .

+1

, , Google . , , - , .

pipe, :

pipe PARENTRECEIVE,CHILDSEND;

. , , ( SIG), :

my $pid = fork();
if ($pid eq 0) {
  #child block
  my $cid = $$;       
  print CHILDSEND "$cid\n";
  <do child stuff which might hang>
}
else {
  #parent block
  my $child_id = <PARENTRECEIVE>;
  chomp $child_id;
  <do parent stuff>
  <if you think child is hung> {
    kill 1, $child_id;
  }
}

- , , , HTTP GET . URL- , , , , - .

+1

, . "" (, waitpid, , , ).

- , , . - , fork , , CPAN, . , . , , .

, perldoc perlfork, , .

0

All Articles