Python协程调度核心是单线程内由asyncio事件循环驱动的协作式并发,依赖await显式挂起恢复、I/O自动让出控制权,需用aiohttp等异步库避免阻塞。
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),此时函数体并未执行——它只是个待调度的“任务描述”。必须将它交给事件循环执行(例如用 await 或 asyncio.create_task())。
async def fetch(): return "done" → fetch() 返回协程对象,不是结果await fetch() 才真正执行,并返回 "done"
asyncio.create_task(fetch()) 把协程包装成 Task 并立即调度,适合并发启动asyncio 的高效依赖于“可等待对象”(awaitable)对 I/O 的封装。真正的系统级阻塞调用(如 time.sleep()、requests.get())会卡住整个事件循环。必须使用 asyncio 原生支持的异步 I/O:
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 可被取消、查询状态、添加回调。
task = asyncio.c
reate_task(coroutine) 是推荐的并发启动方式await task 等待其完成;task.cancel() 可中断执行(协程需响应 CancelledError)asyncio.gather(a, b, c) 并发运行多个协程并收集结果asyncio.wait_for(task, timeout=2) 为单个任务设置超时不复杂但容易忽略:asyncio 不是多线程,也不是多进程,它靠协作式并发在单线程里榨干 I/O 等待时间。写 async 函数只是第一步,关键在用对 await 点、选对异步库、管好事件循环生命周期。