尧图网站建设 尧图网络
  • 首页
  • 关于我们
  • 服务项目
  • 案例展示
  • 建站流程
  • 资讯中心
  • 联系我们
首页/资讯中心/详情

异步 IO

异步 IO
📅 发布时间:2026/6/19 15:09:27

目录
  • 进程与线程
  • 同步与异步,阻塞与非阻塞
  • asyncio库

进程与线程

  • 在我们在终端用python命令启动一个程序的时候,就是创建了一个python进程
  • 进程包含一个或者多个线程,以及其他各种资源。
    • 真正执行代码的是线程
    • 可以把进程想象成一个公司,线程就是这个公司里面的员工。公司除了员工,当然还有其他很多东西。
    • 一个进程至少有一个线程,这个线程叫做主线程
      • 如果程序不包含threading库等,那么这个进程一般只有一个线程,就是主线程
  • 一个CPU核心在同一时间只能执行一个线程
    • 超线程也是这样的,超线程只是用了更高级的切换线程的方式
    • 一个进程的线程可以在不同的CPU核心中被执行,哪个核心有空就在哪个核心执行
    • 所以其实进程数目不是根本因素,线程数目才是根本因素。看CPU是否有空闲/利用率是否高,就看其是否一直在执行线程

同步与异步,阻塞与非阻塞

老张爱喝茶,废话不说,煮开水。 出场人物:老张,水壶两把(普通水壶,简称水壶;会响的水壶,简称响水壶)。 1 老张把水壶放到火上,立等水开。(同步阻塞) 老张觉得自己有点傻 2 老张把水壶放到火上,去客厅看电视,时不时去厨房看看水开没有。(同步非阻塞) 老张还是觉得自己有点傻,于是变高端了,买了把会响笛的那种水壶。水开之后,能大声发出嘀~~~~的噪音。 3 老张把响水壶放到火上,立等水开。(异步阻塞) 老张觉得这样傻等意义不大 4 老张把响水壶放到火上,去客厅看电视,水壶响之前不再去看它了,响了再去拿壶。(异步非阻塞) 老张觉得自己聪明了。

所谓同步异步,只是对于水壶而言。 普通水壶,同步;响水壶,异步。 虽然都能干活,但响水壶可以在自己完工之后,提示老张水开了。这是普通水壶所不能及的。 同步只能让调用者去轮询自己(情况2中),造成老张效率的低下。

所谓阻塞非阻塞,仅仅对于老张而言。 立等的老张,阻塞;看电视的老张,非阻塞。 情况1和情况3中老张就是阻塞的,媳妇喊他都不知道。虽然3中响水壶是异步的,可对于立等的老张没有太大的意义。所以一般异步是配合非阻塞使用的,这样才能发挥异步的效用。

这个例子中,老张相当于线程,水壶相当于IO请求,所以就是说同步异步就是指请求是否通知线程(关注的是消息通知机制),阻塞非阻塞就是指线程是否继续执行(关注的是调用者(线程)在等待结果时的状态)

asyncio库

  • 在函数前加上async可以把函数变成协程
    • 调用协程不会执行函数,只会得到一个协程对象
    • 协程对象的执行需要通过asyncio.create_task()和asyncio.gather()等
  • asyncio.run() 的作用是:启动异步程序,运行一个顶级协程,并在结束后自动关闭事件循环
  • asyncio.create_task()的作用是把协程包装成一个 Task 并立即调度到事件循环中并发执行,从而让它“后台”运行,而不必等待它完成才能继续往下走
  • asyncio.gather()的作用是并发启动多个协程,等它们全部完成,然后把所有返回值按顺序收集成一个列表返回
  • await如果跟的是非IO语句,意义不大
  • asyncio库不会创建其他进程或者线程
    • 创建进程是multiprocessing库
    • 创建线程是threading库
    • asyncio库仍然是单线程执行,只不过不同的Task轮流执行

下面是一些具体的例子:

  • import asyncio
    from openai import AsyncOpenAIclient = AsyncOpenAI(api_key="sk-1234",base_url="http://0.0.0.0:4000"
    )async def chat(message: str) -> str:"""单个异步请求"""response = await client.chat.completions.create(model="my-model",messages=[{"role": "user", "content": message}])return response.choices[0].message.contentasync def main():# 定义多个独立的请求messages = ["What LLM are you?","Could you please tell 1+1 =?","I want to make friends with you.","Tell me a joke.","What is Python?",]# 使用 asyncio.gather 并发执行所有请求tasks = [chat(msg) for msg in messages]results = await asyncio.gather(*tasks)for msg, result in zip(messages, results):print(f"Q: {msg}\nA: {result}\n")# 运行
    asyncio.run(main())
    
    • 线程一直执行到tasks = [chat(msg) for msg in messages],然后这个语句创建了若干协程对象
    • results = await asyncio.gather(*tasks)
      • await将main函数挂起,意思是等到asyncio.gather(*tasks)执行结束之后再继续执行下面的代码
      • asyncio.gather(*tasks)会把这些协程对象封装成 Task(如果还没封装的话),并注册到事件循环中
        • 同一时刻线程只能够执行一个Task
        • 当线程执行到某个Task的await client.chat.completions.create的时候,await会将当前Task挂起,控制权交还给事件循环,事件循环会查看“还有谁准备好了?”,然后让线程去执行下一个 Task
        • 最后所有协程对象执行都完毕了之后,将所有协程对象的执行结果按序放到results中
  • import asyncioasync def chat(msg: str) -> str:print(f"开始处理: {msg}")await asyncio.sleep(1)  # 模拟网络请求print(f"完成处理: {msg}")return f"回复: {msg}"async def main():messages = ["A", "B", "C"]print("=== 串行执行 ===")for msg in messages:result = await chat(msg)print(result)asyncio.run(main())
    
    • 线程执行到result = await chat(msg)的时候,await让main挂起,线程去继续执行chat
    • 线程执行到await asyncio.sleep(1)的时候,会将chat挂起
    • 所以这个代码实际上线程是有空闲的(阻塞),不能实现异步IO

可以使用multiprocessing库开多个进程,每个进程里面使用asyncio库进行异步IO以最大化利用CPU资源

相关新闻

  • 2025年雅思培训黑马机构测评:这些宝藏选择更出分 - 品牌测评鉴赏家
  • 融合经济学与优化的新型仓储容量管理系统
  • 雅思报班避坑指南:2025年口碑黑马机构测评与选择攻略 - 品牌测评鉴赏家

最新新闻

  • 2026万国手表回收避雷手册,助力上海表主避开回收行业各类常见猫腻 - 奢品小当家
  • 天农凤中皇常见问题解答(2026专家版) - 速递信息
  • 1-1 Coursera吴恩达《神经网络与深度学习》第一周学习精要:从房价预测看AI核心
  • 广州花都老板娘想找人教自己管账,找哪家财税公司靠谱?| 4招判断教学型财税公司 - 欢欢在创业
  • ComfyUI-MultiGPU终极指南:一键释放GPU显存,多GPU智能分配技术详解
  • FPGA_Webserver ARP协议实现:千兆速度下的地址解析协议硬件加速

日新闻

  • 5分钟掌握Python进化算法:Geatpy高性能优化工具完全指南
  • Microchip 24AA044 EEPROM选型与应用全指南:从参数解析到实战编程
  • 华为的鸿蒙到底有多牛?为什么称作遥遥领先?

周新闻

  • 3步解锁iOS设备:applera1n激活锁绕过完全指南
  • 39 2026 人工智能证书终极盘点,普通人选 AI 证书可以从这些方向入手
  • Redis 暴露公网有多危险?从端口检查到补救步骤

月新闻

  • 【总结】入门篇:50句话让你记住架构核心概念
  • WeChatMsg技术方案解析:实现Mac微信数据自主管理的完整解决方案
  • WeChatMsg:革新性微信数据备份方案,打造你的专属数字记忆库

关于尧图

  • 公司简介
  • 团队介绍
  • 企业文化
  • 荣誉资质

服务项目

  • 定制开发
  • 电商建站
  • UI 设计
  • 运维服务

快速链接

  • 案例展示
  • 建站流程
  • 常见问题
  • 资讯中心

联系方式

  • 📍北京市朝阳区互联网产业园 A 座 10 层
  • 📞400-888-8888
  • ✉️contact@rkmt.cn
  • 🕐周一至周日 9:00-21:00

© 2024 北京尧图网络科技有限公司 版权所有 | 京 ICP 备 XXXXXXXX 号