asyncio协程是单线程内基于事件循环的并发机制,适用于I/O密集型任务,需用await或asyncio.run()执行,避免阻塞事件循环。

asyncio协程不是多线程,也不是多进程
协程是单线程内的并发调度机制,靠事件循环(event loop)控制多个协程的挂起与恢复。它不创建新线程或进程,因此没有线程切换开销,也不涉及锁竞争。适合 I/O 密集型任务,比如网络请求、文件读写、数据库查询等。CPU 密集型任务用协程反而可能因阻塞事件循环而降低性能。
async/await 是协程的语法糖,不是魔法
定义协程函数只需在 def 前加 async,调用时返回一个协程对象,不会立即执行。必须通过 await(在另一个协程内)或 asyncio.run() 才会真正运行。常见误区是把普通函数改成 async 却忘了 await,结果只是生成了个未被调度的对象,什么也没发生。
- await 只能在 async 函数里用,直接在模块顶层或同步函数中写 await 会报 SyntaxError
-
await 后面必须是可等待对象(Awaitable):协程、Task、Future 或实现了
__await__的对象 -
return 和 yield 不能共存于同一个 async 函数中,async generator 要用
async def ... yield
合理使用 Task 和 create_task 提升并发粒度
直接 await coro 是顺序执行;想真正并发,得用 asyncio.create_task(coro) 把协程包装成 Task 并立即调度。Task 是 asyncio 中的“轻量级并发单元”,比直接 await 更灵活——可以取消、检查状态、设置回调。
- 多个 IO 请求不要串着 await,改用
await asyncio.gather(t1, t2, t3)或先create_task再await对应 Task - 长时间运行的协程建议定期
await asyncio.sleep(0)让出控制权,避免饿死其他任务 - 注意 Task 的生命周期:未 await 的 Task 可能被垃圾回收,尤其在函数退出后
性能优化的关键不在“快”,而在“不浪费”
asyncio 的优势不是单次操作更快,而是单位时间内处理更多请求。优化方向集中在减少阻塞、提升吞吐、避免意外同步化。
立即学习“Python免费学习笔记(深入)”;
- 用
aiohttp替代requests,用aiomysql/asyncpg替代同步驱动,确保所有 I/O 都真正异步 - CPU 密集工作(如解析 JSON、加密计算)要丢给
loop.run_in_executor(),防止阻塞事件循环 - 避免在协程中调用 time.sleep()、print() 过多(虽不阻塞但影响可读性和日志吞吐),调试时可用
logging配合异步 handler - 生产环境开启
asyncio.set_event_loop_policy(asyncio.WindowsSelectorEventLoopPolicy())(Windows)或使用 uvloop(Linux/macOS)替代默认事件循环,可提升 20%~50% 吞吐











