【问题标题】:Can't create new event loop after calling loop.close asyncio.get_event_loop in Python3.6.1在 Python3.6.1 中调用 loop.close asyncio.get_event_loop 后无法创建新的事件循环
【发布时间】:2017-04-28 01:14:53
【问题描述】:

在 Python3.6.1 中,在从 asyncio.get_event_loop() 获得的循环上调用 loop.close() 后,可以创建一个新循环吗?

我查看了其他帖子,其中包含正确关闭循环的答案,以及如何使用 task.cancel(),但无法以允许新循环的方式使用这些示例中的任何一个在第一个关闭后创建。我还尝试显式设置执行程序,然后调用 executor.shutdown(wait=True),但这并没有帮助。我还尝试了 'del loop' 和 del 其他一些东西。

文档表明关闭事件循环是幂等且不可逆的。这是否也意味着无法创建新循环?

这里有一些简单的示例代码来演示这个问题: `

#!/usr/bin/env python3.6
'''
To demonstrate an issue, the following code was adapted from:
https://docs.python.org/3/library/asyncio-eventloop.html
'''
import asyncio

def hello_world(loop):
    print('Hello World')
    loop.stop()

loop = asyncio.get_event_loop()
loop.call_soon(hello_world, loop)
loop.run_forever()
# loop.close()


'''
If the commented out loop.close() above is uncommented,
the following code will fail with:
    Traceback (most recent call last):
        File "./aquestion.py", line 28, in <module>
            loopNew.call_soon(hello_world, loopNew)
        File "/Library/Frameworks/Python.framework/Versions/3.6/lib    /python3.6/asyncio/base_events.py", line 573, in call_soon
        self._check_closed()
        File "/Library/Frameworks/Python.framework/Versions/3.6/lib/python3.6/asyncio/base_events.py", line 357, in _check_closed
            raise RuntimeError('Event loop is closed')
    RuntimeError: Event loop is closed

'''
loopNew = asyncio.get_event_loop()
loopNew.call_soon(hello_world, loopNew)
loopNew.run_forever()

`

任何回答我的问题的尝试都将不胜感激。

或者,创建一个事件循环,将其用于各种目的,然后在长时间运行的程序即将退出时关闭该循环,这会是一种糟糕的形式吗?这似乎是错误的。

【问题讨论】:

    标签: python python-3.x python-asyncio


    【解决方案1】:

    asyncio.get_event_loop 返回当前循环。它不注意循环的状态。如果你在关闭一个循环后需要一个新的循环,你可以使用asyncio.new_event_loop

    请注意,获取新循环不会影响对get_event_loop 的后续调用。如果您希望它返回您的新循环而不是原始循环(尤其是因为您可能已经关闭了它),您需要自己致电asyncio.set_event_loop

    import asyncio
    
    async def f():
        await asyncio.sleep(0)
    
    loop = asyncio.get_event_loop()
    loop.run_until_complete(f())
    loop.close()
    
    loop = asyncio.new_event_loop()
    asyncio.set_event_loop(loop)
    

    【讨论】:

    • 非常感谢!!!那效果很好。我之前尝试过 new_event_loop,但在那个实验中我一定做错了什么。
    • 我忽略了set_event_loop。这可能与您遇到的问题有关。我已经更新了答案以包含它。
    • 为了后代 - 包 asyncio 中的大多数函数接收可选参数 loop
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2022-12-28
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-02-01
    • 2010-09-08
    • 2022-06-25
    相关资源
    最近更新 更多