[英]gevent, requests and unhandled exception
我有代碼:
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)
腳本始終無輸出,一切正常。
編輯:
在主程序退出后,這似乎與嘗試執行處理(例如打印到stdout / stderr)的線程有關。
有關參考,請參見Python錯誤:issue1722344 ,
和Martijn Pieters在此答案中對類似SO問題的評論:
確實,由於python正在退出並且仍然有活動的線程而產生了錯誤。
先前的答案(完全不正確):
您正在體驗的是monkey_patch
有趣的副作用之一。
requests
將socket
用作將數據通過Internet傳輸到某個地址的基礎機制。 gevent.monkey.patch_all()
替換STDLIB socket
與gevent.socket
,它是一個異步(非阻塞)插座,並因此當某處的代碼內的深處(我的猜測去http.client
其中使用由urllib
,這依次由requests
所使用),在該處執行sock.recv(X)
命令,在接收到X個字節或關閉套接字之前 ,代碼將一直阻塞 ,因為套接字已被gevent.socket
替換gevent.socket
,它返回的字節數立即與流緩沖區中當前字節數立即返回 ,代碼中斷。
但是,在您的情況下,簡單的解決方案是只使用grequests ,這是使用gevent構建的請求(實際上,它是自己做的monkey_patch。)
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.