在新循环上运行时,异常“线程'MainThread'中没有当前事件循环”
问题内容:
是简单的测试代码和结果。
import asyncio
async def test():
await asyncio.sleep(1)
if __name__ == '__main__':
asyncio.set_event_loop(None) # Clear the main loop.
loop = asyncio.new_event_loop() # Create a new loop.
loop.run_until_complete(test()) # Run coroutine over the new loop
Traceback (most recent call last):
File "test_test.py", line 11, in <module>
loop.run_until_complete(test())
File "/usr/lib/python3.5/asyncio/base_events.py", line 387, in run_until_complete
return future.result()
File "/usr/lib/python3.5/asyncio/futures.py", line 274, in result
raise self._exception
File "/usr/lib/python3.5/asyncio/tasks.py", line 239, in _step
result = coro.send(None)
File "test_test.py", line 5, in test
await asyncio.sleep(1)
File "/usr/lib/python3.5/asyncio/tasks.py", line 510, in sleep
loop = events.get_event_loop()
File "/usr/lib/python3.5/asyncio/events.py", line 632, in get_event_loop
return get_event_loop_policy().get_event_loop()
File "/usr/lib/python3.5/asyncio/events.py", line 578, in get_event_loop
% threading.current_thread().name)
RuntimeError: There is no current event loop in thread 'MainThread'.
我运行async def test()
过new loop
,并预计asyncio.sleep(1)
这是由嵌套test()
也使用new loop
。
与此相反,sleep()
似乎仍然可以访问main loop
我设置为的内容None
。
我知道我可以在调用之前将amain loop
重置为new loop
with
,它将毫无例外地起作用。asyncio.set_event_loop(loop)``run_until_complete()
不过,我想知道这是正常的,asyncio
是main loop
必须设置并用于协同程序,无论在哪个协同程序运行一个循环。
问题答案:
我想知道
asyncio
该主循环是正常的,无论协程运行在哪个循环上,都必须将其设置为用于协程。
在Python
3.6之前,这是必需的。原因是像这样的功能asyncio.sleep()
需要事件循环才能loop.call_later()
用来安排唤醒呼叫以完成未来。
从Python
3.6(或3.5.3,包括对问题的修复程序)开始,get_event_loop()
从事件循环驱动的协程调用时,它总是返回驱动它的事件循环。结果,您的代码可以正常工作。
联机文档中未提及新行为,但在docstring中有:
从协程或回调(例如,使用预定的
call_soon
API或类似的API进行调用)时,此函数将始终返回正在运行的事件循环。