Asyncio RuntimeError: Event Loop is Closed
Asyncio RuntimeError: Event Loop is Closed
我正在尝试使用 Asyncio 和 aiohttp 库发出一堆请求 (~1000),但我 运行 遇到了一个我找不到太多信息的问题。
当我 运行 这段代码有 10 个 url 时,它 运行 就好了。当我 运行 它有 100 多个 url 时,它会中断并给我 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()
可以找到堆栈跟踪 here。
任何帮助或见解将不胜感激,因为我已经为此苦苦思索了几个小时。显然,这表明事件循环已关闭但仍应打开,但我不明白这是怎么可能的。
你是对的,loop.getaddrinfo 在线程中使用 ThreadPoolExecutor
到 运行 socket.getaddrinfo
。
您正在使用 asyncio.wait_for 超时,这意味着 res = yield from asyncio.wait_for...
将在 4 秒后引发 asyncio.TimeoutError
。然后 get_status
协程 return None
并且循环停止。如果作业在此之后完成,它将尝试在事件循环中安排回调并引发异常,因为它已经关闭。
错误被归档为 https://github.com/python/asyncio/issues/258
敬请期待。
作为快速解决方法,我建议使用自定义执行程序,例如
loop = asyncio.get_event_loop()
executor = concurrent.futures.ThreadPoolExecutor(5)
loop.set_default_executor(executor)
在完成你的程序之前,请做
executor.shutdown(wait=True)
loop.close()
我正在尝试使用 Asyncio 和 aiohttp 库发出一堆请求 (~1000),但我 运行 遇到了一个我找不到太多信息的问题。
当我 运行 这段代码有 10 个 url 时,它 运行 就好了。当我 运行 它有 100 多个 url 时,它会中断并给我 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()
可以找到堆栈跟踪 here。
任何帮助或见解将不胜感激,因为我已经为此苦苦思索了几个小时。显然,这表明事件循环已关闭但仍应打开,但我不明白这是怎么可能的。
你是对的,loop.getaddrinfo 在线程中使用 ThreadPoolExecutor
到 运行 socket.getaddrinfo
。
您正在使用 asyncio.wait_for 超时,这意味着 res = yield from asyncio.wait_for...
将在 4 秒后引发 asyncio.TimeoutError
。然后 get_status
协程 return None
并且循环停止。如果作业在此之后完成,它将尝试在事件循环中安排回调并引发异常,因为它已经关闭。
错误被归档为 https://github.com/python/asyncio/issues/258 敬请期待。
作为快速解决方法,我建议使用自定义执行程序,例如
loop = asyncio.get_event_loop()
executor = concurrent.futures.ThreadPoolExecutor(5)
loop.set_default_executor(executor)
在完成你的程序之前,请做
executor.shutdown(wait=True)
loop.close()