Как лучше всего в Perl установить таймер, чтобы остановить длительный процесс?

У меня есть приложение, которое вызывает потенциально длительный процесс. Я хочу, чтобы моя программа, вызывающая этот процесс, отменила ее в любой заданный момент и перешла к следующей записи, когда превышено ограничение по времени. Используя Perl-модуль AnyEvent, я попробовал что-то вроде этого:

#!/usr/bin/env perl

use Modern::Perl '2017';
use Path::Tiny;
use EV;
use AnyEvent;
use AnyEvent::Strict;

my $cv = AE::cv;
$cv->begin;  ## In case the loop runs zero times...

while ( my $filename = <> ) {
    chomp $filename;
    $cv->begin;

    my $timer = AE::timer( 10, 0, sub {
        say "Canceled $filename...";
        $cv->end;
        next;
    });

    potentially_long_running_process( $filename );
    $cv->end;
}

$cv->end;
$cv->recv;

exit 0;

sub potentially_long_running_process {
    my $html = path('foo.html')->slurp;
    my @a_pairs = ( $html =~ m|(<a [^>]*>.*?</a>)|gsi );
    say join("\n", @a_pairs);
}

Проблема в том, что длительные процессы никогда не прекращаются и не отменяются, а просто продолжают работать. Итак, мой вопрос: "Как я могу использовать AnyEvent (и / или связанные модули) для тайм-аута длительной задачи?"

1 ответ

Решение

Вы не упомянули платформу, на которой вы запускаете этот скрипт, но если он работает на *nix, вы можете использовать сигнал SIGALRM, что-то вроде этого:

my $run_flag = 1;

$SIG{ALRM} = sub {
    $run_flag = 0;
}

alarm (300);

while ($run_flag) {
    # do your stuff here
    # note - you cannot use sleep and alarm at the same time
}

print "This will print after 300 seconds";
Другие вопросы по тегам