Future 和 Task 在 asyncio 中扮演着至关重要的角色,它们是同步代码与异步代码之间的桥梁。Future 的抽象层次低于 Task,有时仅用于等待 IO 完成或定时器到期等非协程相关操作。本文作者为清华大学毕业生,具有 C++/Rust/Python 高级工程师资质,同时也是 Python 解释器 CPython 的维护者之一。部分内容...
协程系列3 Python asyncio 中的 Future 和 Task
本文将深入探讨 Python asyncio 中的 Future 和 Task,为读者提供对这些核心概念的全面理解。在学习 asyncio 之前,建议读者先理解协程的定义以及 async def 和 await 的基本用法。
asyncio 是 Python 3.4 版本引入的标准库,它提供了一系列 API,支持异步 I/O、异步网络等操作。同时,它也提供了工具,如协程、任务和事件循环,以编写并发代码。
asyncio 的实现包含 C 语言加速版本和等效的 Python 实现作为备份,二者在目标上一致,本文将基于易于理解的 Python 实现进行讲解。
在 asyncio 中,Future 是同步代码与异步代码之间的桥梁。它记录任务的状态和结果或异常,并允许用户等待结果或取消任务。值得注意的是,Future 具有 `__await__` 方法,当调用 `await` 时,会触发此方法,返回一个生成器,使调用者等待 Future 的完成。
Task 是 Future 的子类,用于将协程对象包装为 Future。Task 的核心逻辑在于 `__step` 方法,它用于执行协程,并处理协程的完成状态。如果协程抛出 `StopIteration` 异常,说明协程执行完毕,并将结果设置到 Future 上。如果协程产生异常,如被取消或接收到退出信号,将相应处理。如果协程yield出的是一个 asyncio.Future 对象,Task 会将自己加入到该 Future 的完成回调中。如果yield出的是 None,Task 会将自己加入到事件循环中。
Task 有三类基本状态:执行中、已完成和已取消。当协程执行完毕或被取消时,Task 会根据情况进入已完成或已取消状态。
在并发执行多个协程时,`asyncio.gather` 函数非常实用,它允许用户同时等待多个协程的执行结果。使用方法是将所有协程、生成器或 Future 对象包装成 Future 对象,并为最终的 `outer` Future 注册完成回调。当所有输入的 Future 对象完成时,`outer` Future 也将完成。
Future 和 Task 在 asyncio 中扮演着至关重要的角色,它们是同步代码与异步代码之间的桥梁。Future 的抽象层次低于 Task,有时仅用于等待 IO 完成或定时器到期等非协程相关操作。
本文作者为清华大学毕业生,具有 C++/Rust/Python 高级工程师资质,同时也是 Python 解释器 CPython 的维护者之一。部分内容由 AI 辅助创作。2024-11-02