【问题标题】:What is best way in Perl to set a timer to stop long-running process?Perl 中设置计时器以停止长时间运行的进程的最佳方法是什么?
【发布时间】:2017-11-19 22:04:35
【问题描述】:

我有一个应用程序调用了一个可能需要长时间运行的进程。我希望我的程序,这个过程的调用者,在任何给定点取消它,并在超过时间限制时继续下一个条目。使用 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(和/或相关模块)来使长时间运行的任务超时?”

【问题讨论】:

  • 我认为最简单的方法可能是分叉一个子进程。
  • this post 中以一种可能的方式计时的分叉进程的一个示例,而在this post 中使用警报的一个示例。还有更多。
  • 您如何定义最佳?实现最快、最高效、最容易阅读?您提出问题的方式是关于个人意见,我们认为这是题外话。请edit 完善。

标签: perl 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";

【讨论】:

    猜你喜欢
    • 2017-01-11
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多