Как указать ограничение времени ожидания для системного вызова Perl? - PullRequest
27 голосов
/ 19 октября 2010

Иногда мой системный вызов переходит в бесконечное состояние. Чтобы избежать этого, я хочу иметь возможность прервать разговор через определенное время.

Есть ли способ указать ограничение времени ожидания до system?

system("command", "arg1", "arg2", "arg3");

Я хочу, чтобы тайм-аут был реализован из кода Perl для переносимости, а не с использованием некоторых функций ОС, таких как ulimit.

Ответы [ 4 ]

28 голосов
/ 19 октября 2010

См. Функцию alarm.Пример из pod:

eval {
    local $SIG{ALRM} = sub { die "alarm\n" }; # NB: \n required
    alarm $timeout;
    $nread = sysread SOCKET, $buffer, $size;
    alarm 0;
};
if ($@) {
    die unless $@ eq "alarm\n";   # propagate unexpected errors
    # timed out
}
else {
    # didn't
}

В CPAN есть модули, которые оборачивают их немного лучше, например: Time::Out

use Time::Out qw(timeout) ;

timeout $nb_secs => sub {
  # your code goes were and will be interrupted if it runs
  # for more than $nb_secs seconds.
};

if ($@){
  # operation timed-out
}
14 голосов
/ 19 октября 2010

Вы можете использовать метод IPC :: Run вместо системного.и установите таймаут.

3 голосов
/ 31 января 2017

Как насчет System :: Timeout ?

Этот модуль расширяет system, чтобы разрешить тайм-аут после указанных секунд.

timeout("3", "sleep 9"); # timeout exit after 3 seconds
0 голосов
/ 30 ноября 2018

Я только что использовал команду timeout в Perl + Linux, что-то, что вы можете проверить следующим образом:

for(0..4){
  my $command="sleep $_";  #your command
  print "$command, ";
  system("timeout 1.1s $command");  # kill after 1.1 seconds
  if   ($? == -1  ){ printf "failed to execute: $!" }
  elsif($?&127    ){ printf "died, signal %d, %scoredump", $?&127, $?&128?'':'no '}
  elsif($?>>8==124){ printf "timed out" }
  else             { printf "child finished, exit value %d", $? >> 8 }
  print "\n";
}

Выход через 4,317 секунды:

sleep 0, child finished, exit value 0
sleep 1, child finished, exit value 0
sleep 2, timed out
sleep 3, timed out
sleep 4, timed out

Команда timeout входит в состав всех основных "обычных" дистрибутивов Linux a.f.a.i.k, входит в состав coreutils.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...