如何在Perl中强制执行确定的超时? [英] How to enforce a definite timeout in perl?

查看:119
本文介绍了如何在Perl中强制执行确定的超时?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在使用LWP从网页下载内容,我想限制它等待页面的时间.

I am using LWP to download content from web pages, and I would like to limit the amount of time it waits for a page.

my $ua = LWP::UserAgent->new;
$ua->timeout(10);
$ua->env_proxy;
$response = $ua->get("http://XML File");
$content = $response->decoded_content;

问题在于服务器有时会死锁(我们试图找出原因),并且请求将永远不会成功.由于服务器认为它是活动的,因此它保持套接字连接处于打开状态,因此LWP :: UserAgent的超时值对我们毫无用处.对请求实施绝对超时的最佳方法是什么?

The problem is that the server will occasionally deadlock (we're trying to figure out why) and the request will never succeed. Since the server thinks it is live, it keeps the socket connection open thus LWP::UserAgent's timeout value does us no good what-so-ever. What is the best way to enforce an absolute timeout on a request?

只要超时达到极限,它就会死掉,而我无法继续执行该脚本! 整个脚本处于一个循环中,在该循环中,它必须顺序获取XML文件. 我真的很想正确处理此超时并使脚本继续到下一个地址.有谁知道如何做到这一点?谢谢!

Whenever the timeout reaches its limit, it just dies and I can't continue on with the script! This whole script is in a loop, where it has to fetch XML files sequentially. I'd really like to handle this timeout properly and make the script continue to next address. Does anyone know how to do this? Thanks!!

推荐答案

我以前在 https://中遇到过类似的问题stackoverflow.com/a/10318268/1331451 .

您需要做的是添加$SIG{ALRM}处理程序并使用 alarm 调用它.在进行呼叫之前,先设置alarm,然后直接将其取消.然后,您可以查看返回的HTTP :: Result.

What you need to do is add a $SIG{ALRM} handler and use alarm to call it. You set the alarm before you do the call and cancel it directly afterwards. Then you can look at the HTTP::Result you get back.

警报将触发信号,Perl将调用信号处理程序.在其中,您可以直接执行die或仅执行die. eval表示die否会破坏整个程序.如果调用了信号处理程序,则alarm会自动重置.

The alarm will trigger the signal, and Perl will call the signal handler. In it, you can either do stuff directly and die or just die. The eval is for the die no to break the whole program. If the signal handler is called, the alarm is reset automatically.

您还可以向处理程序中添加不同的die消息,并稍后使用$@进行区分,如@larsen在其回答中所说.

You could also add different die messages to the handler and differentiate later on with $@ like @larsen said in his answer.

这是一个例子:

my $ua = LWP::UserAgent->new;
my $req = HTTP::Request->new;
my $res;
eval {
  # custom timeout (strace shows EAGAIN)
  # see https://stackoverflow.com/a/10318268/1331451
  local $SIG{ALRM} = sub {
    # This is where it dies
    die "Timeout occured...";
  }; # NB: \n required
  alarm 10;
  $res = $ua->request($req);
  alarm 0;
};
if ($res && $res->is_success) {
  # the result was a success
}

  • perlipc 用于信号.
    • perlipc for signals.
    • 这篇关于如何在Perl中强制执行确定的超时?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆