警报转义 Perl 'eval' 块
alarm Escaping Perl 'eval' block
我有一个 Perl 脚本,可以自动从各种来源下载内容。它在带有 alarm
的 eval
块中进行下载,这样如果花费的时间太长,尝试就会超时:
eval {
alarm(5);
my $res = $ua->request($req);
$status = $res->is_success;
$rawContent = $res->content;
$httpCode = $res->code;
alarm(0);
};
这已经工作了很多年,但是在进行了一些系统更新后,突然间它停止工作了。相反,它命中的第一个源超时,我收到以下错误并且程序终止:
Alarm clock
我做错了什么导致 eval
突然捕捉不到警报?
SIGALRM默认是终止程序,所以你需要处理它。一种常见的方法是在捕获到 SIGALRM 时发出 die
,将其转换为异常,即 eval
-ed.
eval {
local $SIG{ALRM} = sub { die "Timed out" };
alarm(5);
my $res = $ua->request($req);
$status = $res->is_success;
$rawContent = $res->content;
$httpCode = $res->code;
alarm(0);
};
if ($@ and $@ !~ /Timed out/) { die } # re-raise if it is other error
Signal handling is also used for timeouts in Unix, While safely protected within an eval{}
block, you set a signal handler to trap alarm signals and then schedule to have one delivered to you in some number of seconds. Then try your blocking operation, clearing the alarm when it’s done but not before you’ve exited your eval{}
block. If it goes off, you’ll use die() to jump out of the block, much as you might using longjmp() or throw() in other languages.
至于它是如何工作的,我能想到的一件事是 eval
中使用的包有自己的计时器,基于 alarm
,因此取消了你的 alarm
.来自 alarm
Only one timer may be counting at once. Each call disables the previous timer, and an argument of 0 may be supplied to cancel the previous timer without starting a new one.
他们可能在超时时抛出异常,而您有预期的行为。此包行为在更新中发生了变化,现在您的警报正常运行并需要处理。当然,这是一个猜测。
我有一个 Perl 脚本,可以自动从各种来源下载内容。它在带有 alarm
的 eval
块中进行下载,这样如果花费的时间太长,尝试就会超时:
eval {
alarm(5);
my $res = $ua->request($req);
$status = $res->is_success;
$rawContent = $res->content;
$httpCode = $res->code;
alarm(0);
};
这已经工作了很多年,但是在进行了一些系统更新后,突然间它停止工作了。相反,它命中的第一个源超时,我收到以下错误并且程序终止:
Alarm clock
我做错了什么导致 eval
突然捕捉不到警报?
SIGALRM默认是终止程序,所以你需要处理它。一种常见的方法是在捕获到 SIGALRM 时发出 die
,将其转换为异常,即 eval
-ed.
eval {
local $SIG{ALRM} = sub { die "Timed out" };
alarm(5);
my $res = $ua->request($req);
$status = $res->is_success;
$rawContent = $res->content;
$httpCode = $res->code;
alarm(0);
};
if ($@ and $@ !~ /Timed out/) { die } # re-raise if it is other error
Signal handling is also used for timeouts in Unix, While safely protected within an
eval{}
block, you set a signal handler to trap alarm signals and then schedule to have one delivered to you in some number of seconds. Then try your blocking operation, clearing the alarm when it’s done but not before you’ve exited youreval{}
block. If it goes off, you’ll use die() to jump out of the block, much as you might using longjmp() or throw() in other languages.
至于它是如何工作的,我能想到的一件事是 eval
中使用的包有自己的计时器,基于 alarm
,因此取消了你的 alarm
.来自 alarm
Only one timer may be counting at once. Each call disables the previous timer, and an argument of 0 may be supplied to cancel the previous timer without starting a new one.
他们可能在超时时抛出异常,而您有预期的行为。此包行为在更新中发生了变化,现在您的警报正常运行并需要处理。当然,这是一个猜测。