2017-11-19 13 views
1

長期的に実行される可能性のあるプロセスを呼び出すアプリケーションがあります。このプロセスの呼び出し元である私のプログラムは、任意の時点でキャンセルし、制限時間を超えたときに次のエントリに移動します。彼らはちょうど行き続ける、長期実行プロセスを停止するタイマーを設定するには、Perlではどのような方法が最適ですか?

#!/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); 
} 

問題は長時間実行プロセスがタイムアウトしないとキャンセル飽きないです:PerlのAnyEventモジュールを使用して、私はこのような何かを試してみました。ですから、私の質問はです。「AnyEvent(および/または関連モジュール)を使用して長期実行タスクをタイムアウトするにはどうすればよいですか?

+1

をおそらく子プロセスをフォークします。 – melpomene

+1

[this post](https://stackoverflow.com/a/45250716/4653379)にはフォークされたプロセスの1つの例がありますが、これは[this post](https ://stackoverflow.com/questions/44533600/perl-host-to-ip-resolution/44535265#44535265)。そこにははるかに多くがあります。 – zdim

+0

_best_をどのように定義しますか?最速の実装、最も効率的な、最も読みやすい?あなたの質問には個人的な意見がありますが、ここではその話題とはみなされません。 [編集]して改良してください。 – simbabque

答えて

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"; 
関連する問題