所有任务完成后如何终止python asyncio event_loop

Posted

技术标签:

【中文标题】所有任务完成后如何终止python asyncio event_loop【英文标题】:How to terminate a python asyncio event_loop when all tasks have completed 【发布时间】:2017-08-01 21:50:06 【问题描述】:

好的,所以基本上我需要澄清 RE:如何使用 asyncio.run_until_complete(Future) 函数。

在我的循环中添加 3 个任务后,我尝试使用 asyncio.wait() 函数创建一个 Future"done callback"。

在以下代码中,我的 event_loop.close() 永远不会运行:

import asyncio

async def repeat_message(message, interval_seconds, max_iters=10):
    iters = 0
    while True:
        print(message)
        if iters >= max_iters:
            return 'Complete.'
        iters += 1
        await asyncio.sleep(interval_seconds)

if __name__ == "__main__":
    message_A = "xXxXxXxXxXxXxXxXxXxXx"
    interval_A = 0.5
    message_B = "I LOVE"
    interval_B = 1
    message_C = "EXPLOSIONS!"
    interval_C = 1.5

    event_loop = asyncio.get_event_loop()

    task_A = event_loop.create_task(repeat_message(message_A, interval_A))
    task_B = event_loop.create_task(repeat_message(message_B, interval_B))
    task_C = event_loop.create_task(repeat_message(message_C, interval_C))

    completed = event_loop.create_future()
    completed.add_done_callback(asyncio.wait([task_A, task_B, task_C], loop=event_loop))
    try:
        event_loop.run_until_complete(completed)
    finally:
        event_loop.close()
    # Never prints.
    print('DONE')

【问题讨论】:

【参考方案1】:

这就是gather 的用途。摆脱你的completed 未来,并以这种方式使用gather

event_loop.run_until_complete(asyncio.gather(task_A, task_B, task_C))

您在此处编写的内容创建了一个Future 并对其进行配置,以便在未来完成时,然后它将等待任务。但是你永远不会完成未来(例如set_result())。 Future 并不是真正的异步运行。它只是一个数据结构,表示“某些未来值将由最终调用set_result() 或引发set_exception() 异常的人提供。”事实证明,这通常对异步工作很有用,但它本身并不是协程。

【讨论】:

好棒!那行得通(并且有道理!)谢谢!这实际上揭示了我对为什么 FuturesTasks 需要成为不同实体的一些问题。如果我错了,请更正概括,但是:Task 必须是非阻塞的,它的超类 Future 的实例不需要是这样,这使得它们可以用作控制结构。 如果你有一个任务列表而不是单个变量怎么办?我试过这个,它抛出一个错误“unhasable type: 'list'”

以上是关于所有任务完成后如何终止python asyncio event_loop的主要内容,如果未能解决你的问题,请参考以下文章

如何使用 asyncio 和 concurrent.futures.ProcessPoolExecutor 在 Python 中终止长时间运行的计算(CPU 绑定任务)?

如何在 Python 3.8 中为 asyncio.gather 构建任务列表

使用 asyncio 时,如何让所有正在运行的任务在关闭事件循环之前完成

Python asyncio 任务排序

使用 asyncio 的 Python 网络

python asyncio,如何从另一个线程创建和取消任务