当前位置: 首页 > news >正文

Python 异步编程从入门到实战:告别阻塞,让你的代码效率起飞

你有没有遇到过这样的场景:写了一个批量爬取网页的脚本,单线程跑起来要等十几分钟,中途还容易因为网络波动前功尽弃;写一个接口服务,一个耗时的数据库查询就能把整个服务拖慢,其他请求都得排队。

这些问题的根源,大多来自同步阻塞的执行方式。而 Python 异步编程,就是解决这类问题的利器。今天我们就从原理到实战,一篇搞定 Python 异步编程,让你轻松写出高效的非阻塞代码。


一、什么是异步编程?为什么它能让代码更快?

很多人容易把异步和多线程、多进程搞混,这里先给大家理清楚三者的区别:

  • 多进程:多个进程同时运行,适合 CPU 密集型任务,缺点是进程开销大,进程间通信复杂。
  • 多线程:一个进程内的多个线程并发执行,适合 I/O 密集型任务,但受限于 Python 的 GIL(全局解释器锁),同一时间只有一个线程能执行 Python 字节码,无法真正并行 CPU 密集型任务。
  • 异步编程:单线程内的并发执行,在单个线程内处理多个任务,当某个任务等待 I/O(比如网络请求、文件读写)时,线程不会闲着,而是去执行其他任务,没有线程切换的开销,效率更高。

我们可以用一个生活场景来类比:
你去奶茶店点单,同步编程就是"点一杯,等做好,再点下一杯",全程只能干等;多线程就是"雇几个帮手一起做",但人多了协调成本高;而异步编程,就是你点单后,店员在做你的奶茶时,同时去做其他顾客的订单,不浪费任何等待时间。

对于网络请求、数据库操作、文件读写这类 I/O 密集型任务,异步编程的效率优势会被显著提升,这也是它在后端服务、爬虫等场景中被广泛使用的原因。


下面用流程图展示三种并发模型的区别:

任务类型判断

CPU密集型任务?

选择多进程
多个进程并行执行

I/O密集型任务?

Python环境?

选择异步编程
单线程内并发执行

选择多线程
多线程并发执行

优势: 真正并行
劣势: 开销大, 通信复杂

优势: 无线程切换开销
劣势: 需要异步库支持

优势: 并发执行
劣势: GIL限制, 线程切换开销

二、Python 异步编程的核心概念

Python 的异步编程基于asyncio库实现,下面几个核心概念是你必须搞懂的。

1. 协程(Coroutine)

协程是异步编程的基本单元,本质上就是"可以暂停和恢复的函数"。和普通函数不同,协程需要用async def定义,调用协程函数不会立即执行,而是返回一个协程对象,需要由事件循环驱动执行。

importasyncio# 定义一个协程函数asyncdefhello():print("Hello, Async!")# 调用协程函数,得到的是一个协程对象,不会执行coro=hello()print(type(coro))# 输出:<class 'coroutine'>

2. 事件循环(Event Loop)

事件循环是异步编程的"调度器",它负责管理所有协程的执行,决定什么时候执行哪个协程,什么时候切换到其他协程。我们写的异步代码,最终都要交给事件循环来运行。

3.await关键字

await是协程里用来等待一个可等待对象(比如另一个协程、任务、Future 对象)的关键字。当协程执行到await时,会暂停当前协程的执行,把控制权交还给事件循环,让事件循环去执行其他任务,直到等待的操作完成,再恢复当前协程的执行。

4. 任务(Task)

任务是协程的包装器,它把协程对象包装成一个可以被事件循环调度的任务。使用asyncio.create_task()可以把协程包装成任务,让它在后台并发执行。

五、常见坑点与生产环境最佳实践

1. 不要在协程中使用同步阻塞操作

比如time.sleep()、同步的requests.get()、同步的数据库查询,这些操作会阻塞整个事件循环,让异步代码失去优势。所有耗时的 I/O 操作,都要换成对应的异步版本(比如asyncio.sleep()aiohttpasyncpg等)。

2. 避免 CPU 密集型任务

异步编程适合 I/O 密集型任务,不适用于 CPU 密集型任务。如果在协程中执行长时间的 CPU 计算,会阻塞事件循环,其他任务无法执行。对于 CPU 密集型任务,建议使用多进程。

3. 合理控制并发数量

asyncio.gather()会一次性启动所有任务,如果并发数太多(比如几千个请求),可能会导致系统资源耗尽,或者被目标服务器限流。可以用asyncio.Semaphore控制并发数:

importasyncioimportaiohttpasyncdeffetch(session,url,semaphore):asyncwithsemaphore:# 控制并发数asyncwithsession.get(url)asresponse:print(f"请求完成:{url}")asyncdefmain():urls=[f"https://www.example.com/{i}"foriinrange(10)]semaphore=asyncio.Semaphore(3)# 最多同时执行3个请求asyncwithaiohttp.ClientSession()assession:tasks=[fetch(session,url,semaphore)forurlinurls]awaitasyncio.gather(*tasks)asyncio.run(main())

下面是异步编程执行流程的时序图,展示了协程、任务和事件循环之间的交互:

任务3任务2任务1事件循环开发者任务3任务2任务1事件循环开发者单线程内并发执行无线程切换开销事件循环负责调度在I/O等待时切换任务创建任务1、任务2、任务3开始执行任务1await I/O操作(暂停)切换到任务2await I/O操作(暂停)切换到任务3任务3完成I/O完成,恢复任务1任务1完成I/O完成,恢复任务2任务2完成所有任务完成,返回结果

4. 异常处理必不可少

异步任务的异常如果不捕获,会导致任务静默失败,很难排查问题。建议给每个关键的异步任务都加上try-except块,记录日志。


六、总结与后续学习方向

异步编程是 Python 开发中提升 I/O 密集型任务效率的利器,核心就是用单线程实现非阻塞的并发执行,在爬虫、后端服务、消息队列处理等场景中非常实用。

回顾一下本文的核心要点:

  1. 异步编程通过事件循环调度协程,在单线程内实现并发,避免了线程切换的开销。
  2. 协程、事件循环、await、任务是异步编程的四大核心概念。
  3. 异步代码要使用异步 I/O 库,避免同步阻塞操作。
  4. 生产环境中要注意控制并发数、处理异常、设置超时,避免踩坑。

如果你想继续深入学习,可以从这些方向入手:

  • 学习asyncio库的高级用法,比如asyncio.Queue实现生产者-消费者模型。
  • 了解 FastAPI、Tornado 等异步 Web 框架,用异步方式开发后端服务。
  • 学习异步数据库驱动,比如asyncpg(PostgreSQL)、aiomysql(MySQL),实现异步数据库操作。
http://www.jsqmd.com/news/987087/

相关文章:

  • 鸿蒙新特性:Menu 下拉菜单深度解析 —— 工具栏与操作面板
  • 飞书+龙虾!摄影师局域网外使用龙虾实例!
  • stm32f407读取ov7670(无FIFO)图像灰度值
  • 昆明正规黄金回收,资质齐全,特种行业备案可查! - 开心测评
  • 避开这些坑!DS1302与蓝桥杯单片机I/O冲突的排查与解决实录
  • 2026思维导图工具实测:7款主流工具横向对比,按场景选型不踩坑
  • 团队协作必看:如何用.eslintrc和.prettierrc配置文件根治代码风格‘打架’问题
  • Java 8 Optional 深度指南:告别空指针,解锁链式编程
  • 5G前传网络波分连接故障案例:远端波分盒进水导致AAS同步丢失
  • 深入理解ESP32的WiFi省电机制:从TIM、DTIM到Listen-Interval,如何精细调控你的物联网设备功耗
  • MR-ROBOT靶机深度复盘:除了拿Flag,我们还能学到哪些实战渗透思路?
  • 基于 Harmony 6.0 应用的笔记与思维导图应用首页实现
  • ChatGPT不是效率工具,而是日常认知外挂
  • 常用的改机软件 MTK 高通 展讯 紫光展锐 改串 一键新机 怎么做?修改SN NV数据 qcn
  • 手把手教你用TI C2000 Ware库函数重构F28377x CAN通信代码(附中断配置)
  • Java Swing 图形界面编程
  • 机器学习工程师必须掌握的PDF与CDF实战指南
  • 恒美智造熔融指数测定仪厂家推荐:熔体流动速率仪深度解析 - 专业仪器测评品牌推荐
  • 李沐论文精读合集:67 篇深度学习经典论文逐段精读,从 AlexNet 到 Sora,B 站播放百万级的 AI 自学圣经
  • 草地牛火了之后,它后来发生了什么?
  • 旧手机别扔!用Termux和VNC Viewer把它变成你的第二台Ubuntu办公电脑(保姆级教程)
  • CKKS、BFV、BGV的旋转操作对比:选哪个方案更合适你的隐私计算项目?
  • NSK VH20AN高防尘直线导轨技术手册
  • SpringBoot+Vue二手数码产品交易平台源码+论文
  • 从“热情红”到“庄严靛”:如何用CSS变量和Tailwind CSS管理你的品牌色板?
  • 从单机到分布式:用 Go + Eino + DeepSeek V4 构建生产级 Code Review Agent
  • Mensa推理测试:大模型纯逻辑能力压力测绘与增强实践
  • 广州闲置名包出手,认准这家口碑优质回收门店 - 开心测评
  • 为了省地图 API 费用,我们把缓存做到极致,最后还是重构了整个位置服务
  • 拆开一个烧坏的IGBT模块,手把手教你识别过压、过流、过温的“案发现场”