IPC :: Run поддерживает различные таймауты и таймеры , которые также должны работать на Win32.
Basic:
use warnings;
use strict;
use feature 'say';
use IPC::Run qw(run timeout);
my $out;
eval {
run [ qw(sleep 20) ], \undef, \$out, timeout(2) or die "Can't run: $?"
};
if ($@) {
die $@ if $@ !~ /^IPC::Run: timeout/;
say "Eval: $@";
}
timeout
выдает исключение, таким образом eval
.Существуют и другие таймеры с более тонким и управляемым поведением.Пожалуйста, смотрите документацию.
Исключение перебрасывается, если обнаруженное не вызвано таймером IPC::Run
- судя по тому, что версия модуля в моей системе печатает в сообщении, строка начинаетсяс IPC :: Run: время ожидания .Пожалуйста, проверьте, что это в вашей системе.
Хотя некоторые вещи не работают в Windows, таймеры должны, я думаю.Я не могу проверить прямо сейчас.
Сообщается, что, хотя вышеприведенное работает, с более значимой командой на месте SIGBREAK (21)
выдается по истечении времени ожидания, и после обработки процесс остаетсявокруг.
В этом случае завершите его вручную в обработчике
use warnings;
use strict;
use feature 'say';
use IPC::Run qw(run harness timeout);
my $out;
my @cmd = qw(sleep 20);
my $h = harness \@cmd, \undef, \$out, timeout(2);
HANDLE_RUN: {
local $SIG{BREAK} = sub {
say "Got $_[0]. Terminate IPC::Run's process";
$h->kill_kill;
};
eval { run $h };
if ($@) {
die $@ if $@ !~ /^IPC::Run: timeout/;
say "Eval: $@";
}
};
Для того, чтобы можно было использовать kill_kill
модуля, здесь я сначала создаю жгут, который затем становится доступным, когдаобработчик установлен, и на котором kill_kill
может вызываться при его запуске.
Другим способом было бы найти идентификатор процесса (с помощью Win32 :: Process :: Info или Win32 :: Process :: List ) и завершите его с помощью kill
или Win32 :: Process или TASKKILL
.См. этот пост (вторая половина).
Блок добавляется только к (значимо) local
-размеру обработчика сигнала.В реальном коде все это, вероятно, каким-то образом ограничено, поэтому дополнительный блок может не понадобиться.
Обратите внимание, что в Windows нет сигналов POSIX и что Perl эмулирует только несколько очень простых сигналов UNIX вместе сДля Windows SIGBREAK
.