【问题标题】:Exception " There is no current event loop in thread 'MainThread' " while running over new loop运行新循环时出现异常“线程'MainThread'中没有当前事件循环”
【发布时间】:2018-07-13 23:35:18
【问题描述】:

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

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'.

我在new loop 上运行async def test(),并期望test() 嵌套的asyncio.sleep(1) 也使用new loop

与此相反,sleep() 似乎仍然可以访问 main loop 我设置为 None

我知道我可以在调用run_until_complete() 之前将main loop 重新设置为new loopasyncio.set_event_loop(loop),它会正常工作。

但是,我想知道对于asyncio 来说,main loop 必须设置并用于协程是正常的,无论在哪个循环上运行协程。

【问题讨论】:

    标签: python python-3.x python-3.5 python-asyncio event-loop


    【解决方案1】:

    我想知道对于 asyncio 来说,必须设置主循环并用于协程是正常的,无论在哪个循环上运行协程。

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

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

    在线文档中没有提到新行为,但在the docstring

    当从协程或回调调用时(例如,使用call_soon 或类似 API 进行调度),此函数将始终返回正在运行的事件循环。

    【讨论】:

    • 请将 3.7 替换为 3.5.3
    • @Andrew Svetlov,它似乎适用于python 3.5.3,但我在哪里可以找到关于这个问题的固定内容?我在 release note 上找不到任何关于此的提及
    • @AndrewSvetlov 用 3.5.3 替换 3.7 并不能解释为什么 sn-p 在 3.6 上失败。 Python 3.7 是第一个记录get_event_loop() 新行为的版本,我在很多地方都看到它作为 3.7 的创新被提及。找出为什么 OP 的代码在 3.5.3 中工作可能会很有趣,但这并不会改变对 OP 更通用的问题的答案,即是否需要设置事件循环才能使用 asyncio。
    • 实际上该功能是在 Python 3.6 中引入并向后移植到 3.5.3。 sn-p 用的是 3.5,我猜是 3.5.2。
    • @SangminKi​​m 更改在full 3.5 change log,寻找bpo-28613
    猜你喜欢
    • 2020-06-13
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多