Убить зависший дочерний процесс

My Perl скрипт запускает внешнюю программу (которая принимает единственный параметр командной строки) и обрабатывает ее вывод. Изначально я делал так:

my @result = `prog arg`;

Однако оказалось, что программа глючит и в редких случаях непредсказуемо зависает. Как я могу убить программу, если она не закрылась по прошествии определенного времени? Сценарий должен работать как в Windows, так и в Linux, и, насколько я понимаю, сигналы тревоги и вилки не работают (или вообще не работают) в Windows.

Я нашел модуль под названием IPC :: Run , но не могу понять, как его правильно использовать, из его документации. :-( Я пробовал это:

use strict;
use warnings;
use IPC::Run qw(run timeout);
my $in;
my $out;
my $err;
my @result;
my @cmd = qw(prog arg);
run \@cmd, \$in, \$out, \$err, timeout (10) or die "@cmd: $?";
push @result, $_ while (<$out>);
close $out;
print @result;

В качестве теста я создал программу, которая просто спит 60 секунд, выводит строку в stdout и завершает работу. Когда я пытаюсь запустить ее с помощью приведенного выше кода, она зависает на 60 секунд (вместо 10 секунд, как указано в тайм-ауте) и прекращает работу с причудливой ошибкой:

IPC::Run: timeout on timer #1 at C:/Bin/Unix/Perl/site/lib/IPC/Run.pm line 2956

Затем я нашел другой модуль, Proc :: Reliable . Судя по описанию делать именно то, что я хочу. За исключением того, что это не работает! Я попробовал следующее:

use strict;
use warnings;
use Proc::Reliable;

my $proc = Proc::Reliable->new ();
$proc->maxtime (10);
my $out = $proc->run ("prog arg");
print "$out\n";

Он действительно прерывает дочерний процесс через 10 секунд. Пока все хорошо. Но затем я изменил внешнюю программу и заставил ее спать на всего 5 секунд.Это означает, что программа должна завершиться до истечения 10-секундного тайм-аута, указанного в приведенном выше коде, и ее вывод stdout должен быть записан в переменную $ out . Но это не так! Приведенный выше сценарий ничего не выводит.

Есть идеи, как это сделать правильно? (Исправление глючной внешней программы не вариант.) Заранее спасибо.

5
задан Vess 22 February 2012 в 15:39
поделиться