import asyncio
async def my_task(name, delay): print(f"Task {name}: starting") await asyncio.sleep(delay) print(f"Task {name}: finished")async def main(): print("Main: creating tasks") task1 = asyncio.create_task(my_task("A", 1)) task2 = asyncio.create_task(my_task("B", 0.5)) print("Main: tasks created") await task1 await task2 print("Main: finished")asyncio.run(main())事件循环是一个无限循环,它等待并分发事件,协调所有异步操作的执行顺序。
想象一个餐厅经理(事件循环):
顾客(协程)点餐后不会一直站在厨房门口等待
顾客回到座位(挂起),经理记录订单(注册事件)
厨房做好菜(I/O 完成),经理通知对应顾客(恢复协程)
经理在等待期间可以服务其他顾客(并发处理)
没有空闲时间,所有资源都被高效利用
asyncio 事件循环本身运行在单线程中,但 asyncio 可以与多线程协同工作,形成混合架构
事件循环 = 单线程引擎
所有协程在同一个线程中执行
通过 await 点实现协作式多任务
任何时候只有一个协程"活跃"(占用CPU)
没有线程切换开销,没有锁竞争,没有竞态条件
事件循环始终运行在 MainThread
上面代码:代码中main线程有3个协程:main、task1(A)和task2(B)
main协程只在这一行真正让出控制权:await task1 ,此时main协程处于waiting状态,这行代码的字面意思是:"等待 task1 完成"
asyncio.create_task()只是将协程注册到事件循环,不会立即执行。当前协程(main)会继续执行直到遇到await
asyncio是协作式多任务,不是抢占式调度
main WAITING_FOR_TASK1 等待队列 在 await task1 处暂停
task1 READY 就绪队列 被 create_task 创建,可执行
task2 READY 就绪队列 被 create_task 创建,可执行
事件循环只会从就绪队列中选择协程执行,而 main 此时在等待队列中
await asyncio.sleep(1) 时:
✅ 不是阻塞:只是注册一个 1 秒后的定时器
✅ 主动让出:协程明确告诉事件循环"我现在不能继续"
✅ 精准调度:事件循环检查就绪队列,发现 task2 可以运行
✅ 零 CPU 浪费:在等待期间,线程完全休眠
✅ 确定性恢复:1 秒后精确恢复 task1,从 await 之后继续
这是协程,不是线程
await)来实现并发,不像线程那样依赖操作系统的时间片调度2. 事件循环和执行流程
await task1不是将main加入等待队列,而是"挂起当前协程,直到task1完成,同时允许其他任务运行"CPU 密集型 vs I/O 密集型: