所以我一直在这里以及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;
}
我的程序一直在死,我不确定原因。任何帮助,将不胜感激。谢谢!
答案 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