Pat*_*len 14 python python-3.x python-asyncio aiohttp
我正在尝试使用Asyncio和aiohttp库发出一堆请求(~1000),但我遇到了一个我找不到太多信息的问题.
当我用10个网址运行这个代码时,它运行得很好.当我用100多个网址运行它时,它会中断并给我RuntimeError: Event loop is closed错误.
import asyncio
import aiohttp
@asyncio.coroutine
def get_status(url):
code = '000'
try:
res = yield from asyncio.wait_for(aiohttp.request('GET', url), 4)
code = res.status
res.close()
except Exception as e:
print(e)
print(code)
if __name__ == "__main__":
urls = ['https://google.com/'] * 100
coros = [asyncio.Task(get_status(url)) for url in urls]
loop = asyncio.get_event_loop()
loop.run_until_complete(asyncio.wait(coros))
loop.close()
Run Code Online (Sandbox Code Playgroud)
堆栈跟踪可以在这里找到.
任何帮助或洞察都会非常感激,因为我现在已经敲了几个小时.显然,这表明事件循环已经关闭,应该仍然是开放的,但我不知道这是怎么可能的.
And*_*lov 18
该错误归档为https://github.com/python/asyncio/issues/258 敬请期待.
作为快速解决方法,我建议使用自定义执行程序,例如
loop = asyncio.get_event_loop()
executor = concurrent.futures.ThreadPoolExecutor(5)
loop.set_default_executor(executor)
Run Code Online (Sandbox Code Playgroud)
在完成你的程序之前,请做
executor.shutdown(wait=True)
loop.close()
Run Code Online (Sandbox Code Playgroud)
你没错,loop.getaddrinfo使用a ThreadPoolExecutor来运行socket.getaddrinfo一个线程.
你正在使用带有超时的asyncio.wait_for,这意味着res = yield from asyncio.wait_for...将asyncio.TimeoutError在4秒后引发.然后get_status协同程序返回None并且循环停止.如果作业在此之后完成,它将尝试在事件循环中安排回调并引发异常,因为它已经关闭.
| 归档时间: |
|
| 查看次数: |
11282 次 |
| 最近记录: |