[英]gevent, requests and unhandled exception
I have code: 我有代码:
import gevent
import gevent.monkey; gevent.monkey.patch_all()
import requests
def func():
try:
requests.get('http://unavailable-host/')
except:
pass
def main():
jobs = [gevent.spawn(func) for i in xrange(10)]
gevent.joinall(jobs)
if __name__ == '__main__':
main()
This script usually nothing output. 该脚本通常没有输出。 But sometimes (in 1 of 5 runs) i get this message: 但有时(在5次运行中有1次)我收到此消息:
Unhandled exception in thread started by
sys.excepthook is missing
lost sys.stderr
Explain me, why this happen, and what is right solution? 请解释一下,为什么会这样,什么是正确的解决方案? Also, if I add 另外,如果我添加
gevent.sleep(1)
after 后
gevent.joinall(jobs)
script always nothing output, all is ok. 脚本始终无输出,一切正常。
Edit: 编辑:
This seems like it has to do with a thread trying to do stuff (like print to stdout/stderr) after the main program has already exited. 在主程序退出后,这似乎与尝试执行处理(例如打印到stdout / stderr)的线程有关。
See Python Bugs: issue1722344 for reference, 有关参考,请参见Python错误:issue1722344 ,
and Martijn Pieters's comment in this answer to a similar SO question : 和Martijn Pieters在此答案中对类似SO问题的评论:
Indeed, the error is generated because python is exiting and there is still a thread active. 确实,由于python正在退出并且仍然有活动的线程而产生了错误。
Previous (and completely incorrect) answer: 先前的答案(完全不正确):
What you are experiencing is one of the not-so-fun side effects of monkey_patch
. 您正在体验的是monkey_patch
有趣的副作用之一。
requests
uses socket
as the underlying mechanism for transferring data across the internet to some address. requests
将socket
用作将数据通过Internet传输到某个地址的基础机制。 gevent.monkey.patch_all()
replaces the stdlib socket
with gevent.socket
, which is an asynchronous (non-blocking) socket, and so when somewhere deep within the code (my guess goes to http.client
which is used by urllib
, which is in turn used by requests
), where a sock.recv(X)
command is made, where the code is expected to block until X bytes are received or the socket is closed , and instead, because the socket has been replaced by gevent.socket
, which returns immediately with only as many bytes as are currently in the stream buffer , the code breaks. gevent.monkey.patch_all()
替换STDLIB socket
与gevent.socket
,它是一个异步(非阻塞)插座,并因此当某处的代码内的深处(我的猜测去http.client
其中使用由urllib
,这依次由requests
所使用),在该处执行sock.recv(X)
命令,在接收到X个字节或关闭套接字之前 ,代码将一直阻塞 ,因为套接字已被gevent.socket
替换gevent.socket
,它返回的字节数立即与流缓冲区中当前字节数立即返回 ,代码中断。
The easy solution in your case, however, is to simply use grequests , which is requests built to use gevent (and which, in fact, does its own monkey_patch.) 但是,在您的情况下,简单的解决方案是只使用grequests ,这是使用gevent构建的请求(实际上,它是自己做的monkey_patch。)
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.