是简单的测试代码和结果。

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 loopNone

我知道我可以在调用main loop之前用new loopasyncio.set_event_loop(loop)重置为run_until_complete(),它将毫无异常(exception)地工作。

但是,我想知道asyncio是正常的,必须设置main loop并将其用于协程,而不管协程运行所在的循环如何。

最佳答案



在Python 3.6之前,这是必需的。原因是像asyncio.sleep()这样的函数需要一个事件循环才能使用loop.call_later()安排唤醒调用以完成 future 。

从Python 3.6(或3.5.3,其中包括the issue的修复程序)开始,从事件循环驱动的协程调用get_event_loop()时,它总是返回驱动它的事件循环。结果,您的代码可以正常工作。

联机文档中未提及新行为,但在the docstring中:

关于python - 在新循环上运行时,异常 "There is no current event loop in thread ' MainThread'“,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/48606389/

10-16 09:22