【发布时间】:2013-06-22 10:09:35
【问题描述】:
我有一个连接到 URL 并获取一些 json 的 API 管理器。很简单。 切自方法:
req = Request(url)
socket.setdefaulttimeout(timeout)
resp = urlopen(req, None, timeout)
data = resp.read()
resp.close()
它在大多数情况下都能正常工作,但在随机时间间隔内,完成请求需要 5 秒。即使超时设置为 0.5 或 1.0 或其他任何值。 我已经非常仔细地记录了它,所以我 100% 确定需要时间的行是数字 #3(即 resp = urlopen(req, None, timeout))。
我已经尝试了所有关于超时装饰器和计时器等主题的解决方案。 (列出其中一些: Python urllib2.urlopen freezes script infinitely even though timeout is set, How can I force urllib2 to time out?, Timing out urllib2 urlopen operation in Python 2.4, Timeout function if it takes too long to finish )
但是没有任何效果。我的印象是线程在 urlopen 执行某些操作时冻结,完成后它解冻,然后所有计时器和超时返回 w 超时错误。但执行时间仍然超过 5s。
我发现this 旧邮件列表关于 urllib2 和分块编码的处理。因此,如果问题仍然存在,那么解决方案可能是基于 httplib.HTTP 而不是 httplib.HTTPConnection 编写自定义 urlopen。 另一种可能的解决方案是尝试一些多线程魔法......
这两种解决方案似乎都具有侵略性。让我感到困扰的是,超时并没有一直起作用。
脚本的执行时间不超过0.5s很重要。任何人都知道我为什么会遇到冻结或者可能有什么方法可以帮助我?
根据接受的答案更新: 我改变了方法并改用 curl 。与 unix timeout 一起,它可以按我的意愿工作。示例代码如下:
t_timeout = str(API_TIMEOUT_TIME)
c_timeout = str(CURL_TIMEOUT_TIME)
cmd = ['timeout', t_timeout, 'curl', '--max-time', c_timeout, url]
prc = Popen(cmd, stdout=PIPE, stderr=PIPE)
response = prc.communicate()
由于 curl 只接受 int 作为超时,我添加了超时。 timeout 接受浮点数。
【问题讨论】: