gpt4 book ai didi

python - urlopen 随机卡住,超时被忽略

转载 作者:太空宇宙 更新时间:2023-11-03 18:55:48 35 4
gpt4 key购买 nike

我有一个 API 管理器,它连接到 URL 并获取一些 json。很简单。从方法切入:

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 执行某些操作时,线程会卡住,完成后它会解冻,然后所有计时器和超时都会返回超时错误。但执行时间仍然超过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作为超时,所以我添加了超时。超时接受 float 。

最佳答案

查看源代码,timeout值实际上是Python从远程主机接收数据包之间等待的最长时间。

因此,如果将超时设置为两秒,并且远程主机以每秒一个数据包的速率发送 60 个数据包,则超时永远不会发生,尽管整个过程仍需要 60 秒。

由于 urlopen() 函数只有在远程主机发送完所有 HTTP header 后才会返回,因此如果它发送 header 的速度非常慢,您就无能为力。

如果您需要总体时间限制,您可能必须使用非阻塞 I/O 实现自己的 HTTP 客户端。

关于python - urlopen 随机卡住,超时被忽略,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/17300268/

35 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com