最近遇到一个问题,就是在请求服务器下载数据时,经常会超时5s甚至10s以上,这对于大量数据请求是个挺麻烦的事情。设置timeout=1,但是完全不起作用,仍然5s、10s的等待。
本地测试问题还不一样,比如我设置timeout=0.2,实际上允许的都在0.6s以内,粗略估计是限制在了3倍的时长(后来发现偶尔也有0.7s的),超时倒是会正常弹出。
code如下
if imgString is not None and len(str(imgString)) > 0:
req_url = urllib.request.Request(imgString)
try:
response = urllib.request.urlopen(req_url,timeout=1)
imgbuffer = response.read()
except Exception as e:
res_msg = {'status': 00000}
return res_msg
img = Image.open(BytesIO(imgbuffer))
img = cv2.cvtColor(np.asarray(img), cv2.COLOR_RGB2BGR)
经过对比源码内容,发现设置是没有问题的,另外设置全局响应时间也不好使:
import socket
socket.setdefaulttimeout(1)
实践发现没个毛用,而且也是有倍率关系,大概5倍左右。举例,设置时间是0.2s,那么1s内的数据都可以正常请求,喵的耍我。。。。
那这里就不能靠程序自觉了,所以引入装饰器解决问题
def timeout(timeout):
def decor(func):
def wrapper(*args,**kwargs):
res = []
def thread_func():
res.append(func(*args,**kwargs))
t = threading.Thread(target=thread_func)
t.start()
t.join(timeout)
if t.is_alive():
raise TimeoutError("function execution timeout")
return res[0]
return wrapper
return decor
@timeout(1)
def getImg(req_url):
response = urllib.request.urlopen(req_url, timeout=1)
imgbuffer = response.read()
return imgbuffer
。。。。。。
if imgString is not None and len(str(imgString)) > 0:
req_url = urllib.request.Request(imgString)
try:
imgbuffer = getImg(req_url)
except Exception as e:
res_msg = {'status': 40309}
return res_msg
完美解决时限问题,而且设置时间也是比较靠谱的~