Python gevent、请求和未处理的异常

Python gevent、请求和未处理的异常,python,gevent,Python,Gevent,我有密码: 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)] g

我有密码:

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()
此脚本通常没有任何输出。但有时(在5次跑步中的1次)我会收到以下信息:

Unhandled exception in thread started by
sys.excepthook is missing
lost sys.stderr
解释我,为什么会发生这种情况,什么是正确的解决方案?还有,如果我加上

gevent.sleep(1)
之后

脚本始终无输出,一切正常。

编辑:

这似乎与一个线程在主程序退出后试图执行某些操作(比如打印到stdout/stderr)有关

请参阅以供参考

以及Martijn Pieters在回答以下问题时的评论:

事实上,之所以生成此错误,是因为python正在退出,并且仍然有一个线程处于活动状态

之前(完全不正确)的答案:

你正在经历的是
monkey\u patch
的一个不太有趣的副作用

请求
使用
套接字
作为通过internet将数据传输到某个地址的底层机制
gevent.monkey.patch_all()
将stdlib
socket
替换为
gevent.socket
,这是一个异步(非阻塞)套接字,因此当代码深处的某个地方(我猜是
http.client
,它被
urllib
使用,而
请求又使用它)时,在发出
sock.recv(X)
命令的情况下,代码将被阻塞,直到接收到X个字节或套接字关闭,相反,由于套接字已被替换为
gevent.socket
,它立即返回的字节数与流缓冲区中当前的字节数相同,因此代码中断


然而,在您的情况下,简单的解决方案是使用,这是为使用gevent而构建的请求(事实上,它有自己的monkey_补丁)。

当我使用grequests时,我会在控制台中接收ConnectionError。Grequest对我来说不是一个很好的变体,因为我希望以同步方式编写代码并发送不同请求的链。是否有其他变体可以代替gevent.sleep(1)来解决未处理的异常问题?@Chrome-Hmmm。我明白了。在第二次检查中,它看起来与gevent/stdlib套接字问题无关。有关新答案,请参见编辑。
gevent.joinall(jobs)