Perl:每15秒调用一个子程序

时间:2015-09-20 21:54:10

标签: perl sleep alarm die

所以我一直在这里以及perl.org和perlmaven.com上进行一些调查,但我对我正在尝试运行的代码所发生的事情感到困惑。我用谷歌搜索了什么是$ SIG并在here找到了一些东西让我对本地$ SIG 的内容有了一些了解,但是我仍然对他的意思感到困惑:

  

Perl有一个名为%SIG的内置哈希,其中键是操作系统中可用信号的名称。这些值是子程序(更具体地说是对子程序的引用),将在特定信号到达时调用。

     

除了操作系统的标准信号外,Perl还增加了两个内部“信号”。其中一个叫做 WARN ,每次有些代码调用warn()函数时都会触发。另一个称为 DIE ,并在调用die()时触发。

它还在here上说我不应该在闹钟调用中混合睡眠调用,但是在那里解释的内容对我来说似乎是另一种语言。 我很困惑。我在离开子程序时遇到了麻烦而没有它死在我身上。我正在运行的代码就是这个(我从这里的另一篇文章中获取它但是我不想重新发布那篇帖子,因为它是从2011年):

sub checkfind {
didfindchange;
    while ($call_counter <= 20) {
        my $previous_call_finished = 0;
        eval {
            local $SIG{ALRM} = sub { die "Alarm.\n" };
            alarm 15;
            if ($did_find_change eq "false") {
                didfindchange;
                print("Original FIND value: $original_find_value\n");
                print("FIND value: $ems_find_value\n");
            }
            elsif ($did_find_change eq "true") {
                print("FIND changed.\n");
                print("Original FIND value: $original_find_value\n");
                print("FIND value: $ems_find_value\n");
                $previous_call_finished = 1;
            }
            sleep;
        };
        #Propagate unexpected errors.
        die unless $@ eq "Alarm.\n";
        warn "Timed out!\n" unless $previous_call_finished
    }
    return;
}

我的程序一直在死,我不确定原因。任何帮助,将不胜感激。谢谢!

1 个答案:

答案 0 :(得分:2)

通常,人们会对子程序/外部进程使用警报,这可能需要很长时间(等待数据库连接,网络资源,计算成本非常高的计算等)。您必须在任务完成后每次都重置警报alarm(0);根据我的理解,您尝试这样做,如下所示的简单睡眠/超时循环应该适合您。对于更复杂的事物(等待文件事件,网络事件),您可能希望考虑使用EV事件循环perldoc EV或AnyEvent库perldoc AnyEvent

进行编程
#!/usr/bin/env perl

use warnings;
use strict;

use constant TIMEOUT => 10;
use constant SLEEP   => 2;

check_for_something();
exit 0; # Success

sub check_for_something {
    my $start_time = time();
    my $elapsed = 0;
    while ( $elapsed < TIMEOUT ) {
        print "$elapsed seconds have elapsed...";
        my $value = look_for_something();
        print "Value is " . ( $value ? 'true' : 'false' ) . "\n";
        if ($value) {
            print "Value is true...returning\n";
            return "value has changed...";
        }

        sleep SLEEP;
        $elapsed = time() - $start_time;
    }
    die "Timed out after " . TIMEOUT . " seconds!\n";
}

sub look_for_something {
    # !! changes the number into either '1' or 'undef'
    # ! !! inverts the sense
    return ! !! int rand (2 * TIMEOUT / SLEEP); # False most of the time, occasionaly true     
}

<强>输出

perl test_find.pl
0 seconds have elapsed...Value is false
2 seconds have elapsed...Value is false
4 seconds have elapsed...Value is false
6 seconds have elapsed...Value is false
8 seconds have elapsed...Value is false
Timed out after 10 seconds!

perl test_find.pl
0 seconds have elapsed...Value is false
2 seconds have elapsed...Value is false
4 seconds have elapsed...Value is true
Value is true...returning