मैं एक आईआरसी बॉट (Bot::BasicBot) चला रहा हूं जिसमें दो बाल प्रक्रियाएं File::Tail चल रही हैं, लेकिन बाहर निकलने पर, वे समाप्त नहीं होते हैं। इसलिए मैं उन्हें बाहर निकलने से पहले Proc::ProcessTable इस तरह का उपयोग कर killling हूँ:बाहर निकलने से पहले पर्ल में बाल प्रक्रियाओं को मारने का सही तरीका क्या है?
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.
और क्या मैं कर सकता हूँ बच्चे प्रक्रियाओं को बंद करने? फोर्कड प्रक्रिया forkit विधि Bot::BasicBot में विधि का उपयोग करके बनाई गई है।
नमूना स्क्रिप्ट:
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"; }
}
हाय, आप बच्चे की प्रक्रियाओं को कैसे मार रहे हैं इसके साथ कोई समस्या नहीं है। चेतावनी सिर्फ यह कह रही है कि जब आप इन प्रक्रियाओं को मरते हैं तो आपने पीओई कॉलबैक पंजीकृत नहीं किया है - आपको उन्हें POE-> कर्नेल-> sig_child() के साथ पंजीकृत करने की आवश्यकता है। देखें: http://kobesearch.cpan.org/htdocs/POE/POE/Kernel.html#sig_child_PROCESS_ID_EVENT_NAME – Martin