Perl 为什么';是否在报警信号处理器中死亡?是否终止进程?
如何为Perl系统调用指定超时限制Perl 为什么';是否在报警信号处理器中死亡?是否终止进程?,perl,die,Perl,Die,如何为Perl系统调用指定超时限制 eval { local $SIG{ALRM} = sub { die "alarm\n" }; # NB: \n required alarm $timeout; $nread = sysread SOCKET, $buffer, $size; alarm 0; }; if ($@) { die unless $@ eq "alarm\n"; # propagate unexpected errors
eval {
local $SIG{ALRM} = sub { die "alarm\n" }; # NB: \n required
alarm $timeout;
$nread = sysread SOCKET, $buffer, $size;
alarm 0;
};
if ($@) {
die unless $@ eq "alarm\n"; # propagate unexpected errors
# timed out
}
else {
# didn't
}
如果发生超时,则应
sub{die“alarm\n”}代码>导致进程结束。我想我不懂die
。这表示“die()函数用于退出脚本并显示一条消息供用户阅读”。但是,对于上面的脚本,脚本将在#超时时处理代码。sysread也继续工作。我没有使用sysread,而是使用了一个休眠30秒的perl脚本。我的超时设置为10秒。正如预期的那样,执行了#中的代码超时,但脚本继续休眠。从人工报警
alarm() arranges for a SIGALRM signal to be delivered to the calling process in seconds seconds.
在sigalarm交付之前,执行到达else块。在sysread之前插入STDIN,以便sigalarm触发预期结果
“我使用的不是sysread,而是一个休眠30秒的perl脚本
超时设置为10秒。正如预期的那样,#中的代码超时
已执行,但脚本继续休眠。”
真的吗
#!/usr/bin/perl
use strict;
use warnings FATAL => qw(all);
eval {
open my $fh, '<', $0 || die;
local $SIG{ALRM} = sub {
print STDERR "hello!\n";
die "bye!";
};
alarm 3;
while (<$fh>) {
print $_;
sleep 1;
}
close $fh;
};
if ($@) {
print "HERE: $@\n";
}
#/usr/bin/perl
严格使用;
使用致命警告=>qw(全部);
评估{
打开我的$fh,“不会导致进程结束,它会引发异常
现在,如果没有任何东西捕捉到异常,那么流程就结束了,但是您已经准备好捕捉这个异常了
进程不会结束,因为您明确阻止它结束
由于您不太清楚自己的行为是什么,因此可能存在另一种可能性:您使用的是Windows版本的Perl
报警
是一个Unix系统调用。它的用途(经过一定时间后发送信号)在Windows上没有意义,因为Windows没有信号
Perl在某种程度上模拟了报警
,但只以非常有限的方式进行模拟。睡眠
很可能是唯一可被报警
中断的操作。否则,超时只会在语句之间进行检查
因此,它不会中断sysread,但一旦返回,Perl就会注意到超时过期并模拟信号。将Linux Perl脚本移植到Windows时,我也遇到了同样的问题
我通过
创建非阻塞套接字
$recsock = IO::Socket::INET->new(
LocalPort => 68,
Proto => "udp",
Broadcast => 1,
Blocking => 0,
) or die "socket: $@";
将$continue变量添加到超时句柄
# Timeout handle
$SIG{ALRM} = sub {
print "timeout\n";
$continue = 1;
};
当超时发生时,检查$continue是否为true:
alarm($timeout);
while(1){
$recsock->recv($newmsg, 1024);
eval {
$packet = Net::Package->new($newmsg);
...
};
sleep 0.1;
last if ($continue);
}
alarm(0);
@doon,添加了备选答案。谢谢。我正在使用UNIX版本的perl。谢谢你让我知道die是个例外。我没有意识到that@doon相反,有。但通常您希望die
,因为它允许人们根据自己的选择处理错误。@doon,还请注意,SIGALRM通常会终止您的进程,因此您的scr如果不使用local$SIG{ALRM}
,则ipt将强制存在
允许您的析构函数运行。谢谢。这很有用。您在报警后编写的代码(即睡眠例程)与我编写的代码相同。但它是在一个单独的脚本中。感谢您的注释,在命令完成之前,eval将不会完成。尽管这很混乱。如果在其内部包含eval的父进程脚本完成,然后eval必须完成。我希望您理解我的查询。注释框不允许我直观地解释。再次感谢您,如果您将open$0
替换为open my$fh',-|',“sleep 10'| | die;
您就会明白我所说的必须等待子进程(shell睡眠)的意思了.但除此之外,正常命令不应阻止报警。
alarm($timeout);
while(1){
$recsock->recv($newmsg, 1024);
eval {
$packet = Net::Package->new($newmsg);
...
};
sleep 0.1;
last if ($continue);
}
alarm(0);