一、Future 和 Task 的基本概念

1. Future

  • Future 是一个“占位符”,表示将来某个时刻才会有结果的对象。
  • 它有 .result().set_result().done().add_done_callback() 等方法。
  • 在 asyncio 中,Future 主要用于底层通信、回调、手动控制异步结果
  • 你可以把 Future 理解为“一个还没完成的异步操作的结果容器”。

2. Task

  • Task 是 Future 的子类,专门用于调度和管理协程的执行
  • 当你用 asyncio.create_task(coro)loop.create_task(coro) 创建 Task 时,事件循环会自动调度协程的执行,并把协程的返回值设置为 Task 的结果。
  • Task 让协程能被事件循环自动驱动和管理。

二、为什么要有 Task 类?

  • 线程池/进程池中的 Future 只是“结果容器”,由线程池/进程池调度任务。
  • 协程的调度 需要事件循环主动驱动,不能像线程那样自动切换。
  • Task 解决了“如何让协程自动被事件循环调度”的问题:
    • Task 既是 Future(有结果、回调等接口),又能自动驱动协程的执行。

三、接口对比

功能 Future(线程/协程) Task(协程专用)
结果占位符
回调接口
由谁驱动 线程池/进程池/手动 事件循环
自动调度协程
直接 await

四、代码示例与解释

1. Future 只能手动设置结果

import asyncio

async def main():
    fut = asyncio.Future()
    # 模拟异步操作,1秒后设置结果
    asyncio.get_event_loop().call_later(1, fut.set_result, 'future done')
    result = await fut
    print('Future result:', result)

asyncio.run(main())
  • 这里的 Future 只是一个“结果容器”,需要手动 set_result,不能自动驱动协程。

2. Task 自动调度协程

import asyncio

async def foo():
    await asyncio.sleep(1)
    return 'task done'

async def main():
    task = asyncio.create_task(foo())
    result = await task
    print('Task result:', result)

asyncio.run(main())
  • Task 会自动调度 foo 协程的执行,foo 的返回值会自动成为 task 的结果。

3. Task 是 Future 的子类

from asyncio import Task, Future

print(issubclass(Task, Future))  # True
  • Task 继承自 Future,拥有 Future 的全部接口。

五、总结

  • Future 是“结果容器”,需要手动设置结果,不能自动驱动协程。
  • Task 是“可自动调度的 Future”,专为协程设计,能让协程自动被事件循环驱动。
  • 你可以 await Future 或 Task,但只有 Task 能自动调度协程的执行。

六、图示关系

协程对象 <---(包装)--- Task(Future子类) <---(await/回调)--- 你的代码
Logo

Agent 垂直技术社区,欢迎活跃、内容共建。

更多推荐