Python协程调度模型_asyncio解析【教程】

9次阅读

Python 协程调度核心是单线程内由 asyncio 事件循环驱动的协作式并发,依赖 await 显式挂起恢复、I/ O 自动让出控制权,需用 aiohttp 等异步库避免阻塞。

Python 协程调度模型_asyncio 解析【教程】

Python 的协程调度核心是 asyncio 事件循环(Event Loop),它不依赖 操作系统 线程,而是在单线程内通过“挂起 - 恢复”机制协同调度多个 异步任务。理解其模型的关键在于:** 事件循环驱动、协程对象需显式 await、I/O 操作自动让出控制权 **。

事件循环是调度中枢

每个 asyncio 程序有且仅有一个运行中的事件循环(除非手动创建多个)。它持续轮询 I/O 事件(如 socket 可读、定时器到期)、执行就绪的回调和协程,是整个异步调度的“大脑”。

  • 调用 asyncio.run(main()) 会自动创建并启动一个事件循环
  • 手动管理时可用 loop = asyncio.get_event_loop()(Python 3.11+ 推荐 asyncio.get_running_loop()
  • 循环一旦关闭,无法重启;新任务必须在新循环中提交

协程函数与协程对象要分清

async def 定义的是协程函数,调用它返回的是一个协程对象(coroutine object),此时函数体并未执行——它只是个待调度的“任务描述”。必须将它交给事件循环执行(例如用 awaitasyncio.create_task())。

  • async def fetch(): return "done"fetch() 返回协程对象,不是结果
  • await fetch() 才真正执行,并返回 "done"
  • asyncio.create_task(fetch()) 把协程包装成 Task 并立即调度,适合并发启动

I/O 操作是让出控制权的触发点

asyncio 的高效依赖于“可等待对象”(awaitable)对 I/O 的封装。真正的系统级阻塞调用(如 time.sleep()requests.get())会卡住整个事件循环。必须使用 asyncio 原生支持的异步 I/O:

立即学习Python 免费学习笔记(深入)”;

  • 网络请求用 aiohttp 替代 requests
  • 文件操作用 asyncio.to_thread()(Python 3.9+)或 loop.run_in_executor() 转移至线程池
  • 延时用 await asyncio.sleep(1),而非 time.sleep(1)
  • 所有底层基于 select / epoll / kqueue 或 Windows 的 IOCP 实现

Task 和 Future 是调度的基本单元

协程被调度后,通常会被包装为 Task 对象(继承自 Future),代表一个正在运行或已完成的异步操作。Task 可被取消、查询状态、添加回调。

  • task = asyncio.create_task(coroutine) 是推荐的并发启动方式
  • await task 等待其完成;task.cancel() 可中断执行(协程需响应 CancelledError
  • asyncio.gather(a, b, c) 并发运行多个协程并收集结果
  • asyncio.wait_for(task, timeout=2) 为单个任务设置超时

不复杂但容易忽略:asyncio 不是多线程,也不是多进程,它靠协作式并发在单线程里榨干 I/O 等待时间。写 async 函数只是第一步,关键在用对 await 点、选对异步库、管好事件循环生命周期。

星耀云
版权声明:本站原创文章,由 星耀云 2026-01-02发表,共计1366字。
转载说明:转载本网站任何内容,请按照转载方式正确书写本站原文地址。本站提供的一切软件、教程和内容信息仅限用于学习和研究目的;不得将上述内容用于商业或者非法用途,否则,一切后果请用户自负。本站信息来自网络,版权争议与本站无关。
text=ZqhQzanResources