找回密码
 立即注册
首页 业界区 安全 python异步

python异步

丘奕奕 2025-7-5 09:49:44
转载学习:Python: 从async/await理解协程的高效世界
在Python编程的领域中,异步处理就像一位高效的时间管理大师,能让程序在处理IO密集型任务时大幅提升效率。Python 3.5引入的async和await语法糖,让原本复杂的异步编程变得清晰易懂。接下来,我们就通过日常生活中的例子和简单代码,深入理解协程、async/await及asyncio框架的核心概念。


  • IO密集型任务:指任务执行过程中大部分时间花费在等待输入/输出(I/O)操作完成(如网络请求、文件读写、数据库查询等)。在此期间,CPU处于空闲状态,无需进行大量计算。典型场景包括:

    • 网页爬虫(频繁发起网络请求并等待响应)
    • 文件批量读写(等待磁盘数据传输)
    • 数据库交互(等待查询结果返回)

  • CPU密集型任务:指任务执行过程中需要大量CPU计算资源,几乎不涉及I/O等待(如数据加密/解密、图像渲染、科学计算等)。此时CPU持续处于高负载状态,主要用于逻辑运算或数值处理。典型场景包括:

    • 视频编码/解码
    • 大规模数据统计分析
    • 复杂数学模型运算

协程是什么?

想象你来到图书馆,准备度过充实的一天,想一边查阅资料,一边完成练习题。

  • 进程:就好比整个图书馆,是程序运行的环境,里面有各种资源和空间供任务开展。
  • 线程:像是图书馆里不同的自习室,每个自习室可以容纳不同的人做不同的事,它们相对独立又共享图书馆的资源。
  • 协程:则是你本人,在等资料打印出来(IO 等待)的时间里,不会干坐着,而是立刻开始做练习题;当练习题遇到不会的,又切换去看看资料是否打印好。哪件事先有结果(资料打印好了或者做出了一道题)就先处理哪件。这就是协程的核心 —— 在单线程内灵活切换任务,避免因等待IO操作而浪费时间
协程的关键特性:

  • 在单线程内执行,任务切换成本极低
  • 特别适合处理网络请求、文件读写这类IO密集型任务
  • 无法利用多核CPU,处理CPU密集型任务需要搭配多进程
异步和同步

同步执行(串行):
你先去资料室提交打印申请,然后守在打印机旁,直到资料打印完,才回到座位开始做练习题。整个过程总耗时 = 等资料打印的20分钟 + 做练习题的30分钟 = 50分钟
异步执行(并行):
你提交打印申请后,不需要一直等着,立刻回到座位开始做练习题。在做题过程中,资料打印好了就去取,取完资料继续做题。总耗时 = 30分钟(最长任务时间)
核心差异:

  • 同步:任务按顺序依次执行,必须等前一个任务完成才能进行下一个
  • 异步:任务启动后不阻塞后续操作,通过回调或事件通知任务完成
async/await


  • 定义异步函数(协程)
  1. import asyncio
  2. # 用async声明异步函数
  3. async def print_material(duration):
  4.     # await 等待异步操作,不阻塞线程
  5.     await asyncio.sleep(duration)
  6.     print(f'打印材料耗时{duration}秒')
复制代码

  • 执行单个协程
  1. asyncio.run(print_material(2))
复制代码
1.png


  • 并发执行多个任务
  1. async def main():
  2.     # 创建多个任务
  3.     task1 = asyncio.create_task(print_material(2))
  4.     task2 = asyncio.create_task(print_material(3))
  5.     task3 = asyncio.create_task(print_material(1))
  6.     # 等待所有任务完成
  7.     await asyncio.gather(task1, task2, task3)
  8. asyncio.run(main())
复制代码
2.png

其中:await只能用于可等待对象(如asyncio.sleep()),直接使用time.sleep()会阻塞线程。asyncio.create_task()用于注册并发任务,asyncio.gather()可批量等待任务完成
协程和线程

3.png

实际案例:

  • 下载 1000 张图片: 协程方案能在单线程内高效完成,线程方案创建大量线程容易导致资源耗尽
  • 数据加密计算: 线程配合多进程可以利用多核CPU,协程无法提升计算速度
asyncio框架

asyncio是Python内置的异步框架,它就像一个智能管家,负责管理协程的执行流程,其内部实现异步的原理主要包含以下几个关键部分:
4.png

1. 事件循环(Event Loop)
事件循环是 asyncio 的核心,它就像是一个不停运转的 “调度员”。这个调度员手中有一张任务清单,不断地检查清单里的任务是否有可以执行的。当某个协程遇到await时,就会暂停执行,并把执行权交回事件循环。事件循环会记录下这个协程暂停的位置,然后去检查其他任务。一旦await后面的异步操作完成(比如asyncio.sleep()时间结束),事件循环就会把这个协程重新放到任务清单中,等待合适的时机继续执行。
比如,在前面图书馆的例子中,你在等待资料打印时开始做题,这个 “切换任务” 的动作就像是事件循环在调度。当资料打印好这个事件发生,事件循环就会提醒你去取资料。
  1. import asyncio
  2. async def task1():
  3.     print("任务1开始执行")
  4.     await asyncio.sleep(2)
  5.     print("任务1执行完毕")
  6. async def task2():
  7.     print("任务2开始执行")
  8.     await asyncio.sleep(1)
  9.     print("任务2执行完毕")
  10. async def main():
  11.     loop = asyncio.get_event_loop()
  12.     task_list = [loop.create_task(task1()), loop.create_task(task2())]
  13.     await asyncio.gather(*task_list)
  14.    
  15. asyncio.run(main())
复制代码
5.png

其中,事件循环loop负责调度task1和task2,根据await asyncio.sleep()的时间,灵活安排任务的执行顺序。

  • 任务(Task)和Future
asyncio.Task是对协程的进一步封装,它代表一个具体的异步任务。当我们使用asyncio.create_task()创建任务时,实际上是将协程包装成了一个Task对象,并加入到事件循环的任务队列中。Task对象有自己的状态(如 pending、running、done 等),事件循环通过这些状态来管理任务的执行。
Future则用于表示异步操作的最终结果。当一个协程完成时,会将结果存储在对应的Future对象中。比如,当一个网络请求的协程获取到数据后,数据就会存放在相关的Future里,其他协程可以通过await这个Future来获取结果。

  • 回调机制
asyncio支持为任务添加回调函数。当一个异步任务完成时,事件循环会自动调用预先设置的回调函数。这就好比你点外卖时,设置了外卖送达时的提醒,外卖送到后手机就会触发提醒(回调函数执行)。
  1. import asyncio
  2. def callback(future):
  3.     print(f"任务结果:{future.result()}")
  4. async def async_task():
  5.     await asyncio.sleep(3)
  6.     return "任务完成"
  7. async def main():
  8.     task = asyncio.create_task(async_task())
  9.     task.add_done_callback(callback)
  10.     await task
  11. asyncio.run(main())
复制代码
其中,当async_task执行完毕,callback函数就会被调用,输出任务的结果。

  • 协程的挂起和恢复
await关键字是实现协程挂起和恢复的关键。当协程执行到await时,会暂停当前协程的执行,并将控制权交回事件循环。此时,事件循环可以去执行其他可运行的协程。当await后面的操作完成,事件循环会恢复该协程的执行,从暂停的位置继续运行。这种机制使得在单线程内可以高效地处理多个异步任务,避免了因等待IO而造成的线程阻塞。
核心概念:

  • 事件循环(Event Loop):异步任务的调度中心,不断检查任务状态
  • 任务(Task):对协程的封装,用于管理执行状态
  • Future:表示异步操作的最终结果,可通过await获取

来源:豆瓜网用户自行投稿发布,如果侵权,请联系站长删除

相关推荐

您需要登录后才可以回帖 登录 | 立即注册