2

我有代码:

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)

脚本总是没有输出,一切正常。

4

1 回答 1

0

编辑:

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

请参阅Python 错误:issue1722344以供参考,

和 Martijn Pieters 在这个答案中对类似 SO 问题的评论:

实际上,由于 python 正在退出并且仍然有一个线程处于活动状态,所以会生成错误。

以前的(并且完全不正确的)答案:

您正在经历的是monkey_patch.

requests用作socket通过 Internet 将数据传输到某个地址的底层机制。gevent.monkey.patch_all()用 替换 stdlib socketgevent.socket这是一个异步(非阻塞)套接字,因此当代码深处的某个地方(我的猜测http.client是由 使用urllib,而后者又由 使用requests)时,在哪里发出sock.recv(X)命令,代码预计会阻塞,直到收到 X 字节或套接字关闭,相反,因为套接字已被替换gevent.socket,它立即返回只有与流缓冲区中当前一样多的字节,所以代码中断。

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

于 2013-03-20T19:36:57.887 回答