gevent,请求和未处理的异常

时间:2013-03-20 19:26:08

标签: 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)]
    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)

gevent.joinall(jobs)

脚本总是没有输出,一切都好。

1 个答案:

答案 0 :(得分:0)

修改

这似乎与主程序已经退出后尝试执行操作的线程(如print到stdout / stderr)有关。

请参阅Python Bugs: issue1722344以供参考,

和Martijn Pieters在a similar SO question的答案中的评论:

  

实际上,错误是因为python正在退出并且仍然存在活动线程而生成的。

以前(且完全不正确)回答:

您所遇到的是monkey_patch的一个不那么有趣的副作用。

requests使用socket作为通过互联网将数据传输到某个地址的基础机制。 gevent.monkey.patch_all()socket替换了stdlib gevent.socket,这是一个异步(非阻塞)套接字,所以在代码深处的某个地方(我猜到http.clienturllib使用requestssock.recv(X)},其中gevent.socket命令,其中代码预期阻塞,直到收到X字节或套接字已关闭,相反,因为套接字已被{{1}}替换,立即返回的内容只有当前在流缓冲区中的字节数,代码中断

然而,在您的情况下,简单的解决方案是简单地使用grequests,这是使用gevent构建的请求(事实上,它实际上是自己的monkey_patch。)