2013-03-20 111 views
2

我有代码: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() 

这通常脚本没有输出。但有时(在1 5的运行)我得到这个消息:

Unhandled exception in thread started by 
sys.excepthook is missing 
lost sys.stderr 

我解释,为什么出现这种情况,什么是正确的解决方案?另外,如果我加入

gevent.sleep(1) 

gevent.joinall(jobs) 

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

回答

0

编辑:

这似乎是它具有主程序已经退出后做的一个线程试图做的东西(如打印到标准输出/标准错误)。

Python Bugs: issue1722344参考,

和马亭皮特斯在这一回答a similar SO question评论:

事实上,由于蟒蛇正在退出,仍然有活动线程产生的错误。

上一页(完全不正确的)答案:

什么,你遇到的是的monkey_patch的不那么有趣的副作用之一。

requests使用socket作为将数据通过互联网传输到某个地址的基本机制。 gevent.monkey.patch_all()将stdlib socket替换为gevent.socket,它是一个异步(非阻塞)套接字,所以当代码深处的某个位置(我的猜测转到http.client时,urllib使用了urllib,而requests又使用了这个函数),其中a sock.recv(X)命令制成,其中所述代码被预计阻塞,直到X字节被接收或关闭套接字,而是,由于插座已取代gevent.socket,其立即用仅作为许多字节返回如目前在流缓冲区,代码中断。

你的情况最简单的解决方案,但是,是简单地使用grequests,这是要求建成使用GEVENT(并且,事实上,做自己的monkey_patch。)

+0

当我使用grequests我收到_ConnectionError_在安慰。 Grequest对我来说不是很好的变体,因为我想用同步风格编写代码并发送不同请求的链。有没有其他变体来解决_unhandled exception_问题,而不是gevent.sleep(1)? – 2013-03-20 20:49:49

+0

@Chrome嗯。我懂了。在第二次检查中,它看起来与gevent/stdlib-socket问题无关。请参阅编辑新答案。 – 2013-03-20 21:14:31