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

深入理解Python中的并发与异步的结合使用

​ 在上一篇文章中,我们讨论了异步编程中的性能优化技巧,并简单介绍了triocurio库。今天,我们将深入探讨如何将并发编程与异步编程结合使用,并详细讲解如何利用triocurio库优化异步编程中的性能。

文章目录

        • 并发与异步编程的区别与联系
        • 并发编程与异步编程的优缺点
          • 并发编程
          • 异步编程
        • 如何在同一个程序中同时使用 `threading`、`multiprocessing` 和 `asyncio`
          • 使用 `threading` 和 `asyncio`
        • 深入使用 `trio` 库
          • 基本使用
          • 高级功能:取消与超时
        • 深入使用 `curio` 库
          • 基本使用
          • 高级功能:任务取消与超时
      • 性能优化技巧
      • 结语

并发与异步编程的区别与联系

并发编程和异步编程都是处理多任务的有效手段,但它们的实现方式和适用场景有所不同:

  • 并发编程:通过线程或进程来同时执行多个任务,适用于CPU密集型任务;
  • 异步编程:通过事件循环和协程来调度任务,适用于I/O密集型任务。

结合使用并发和异步编程,可以同时处理CPU密集型和I/O密集型任务,提升程序整体性能。

并发编程与异步编程的优缺点
并发编程
  • 优点
    • 可以充分利用多核CPU的优势,提高程序的执行效率;
    • 适用于需要大量计算的任务,例如数据处理、图像处理等。
  • 缺点
    • 线程和进程的管理和调度较为复杂,需要处理同步、锁等问题;
    • 创建和销毁线程或进程会有一定的开销。
异步编程
  • 优点
    • 适用于I/O密集型任务,可以在等待I/O操作完成时执行其他任务,提高资源利用率;
    • 代码更加简洁,逻辑清晰。
  • 缺点
    • 仅能在单线程中运行,不能利用多核CPU的优势;
    • 对于CPU密集型任务效果不佳。
如何在同一个程序中同时使用 threadingmultiprocessingasyncio

在同一个程序中,我们可以利用 threadingmultiprocessing 提供并发能力,同时使用 asyncio 实现异步I/O操作:

使用 threadingasyncio
import asyncio
import threadingasync def async_task():print("Starting async task")await asyncio.sleep(2)print("Async task completed")def sync_task(loop):print("Starting sync task")loop.run_until_complete(async_task())print("Sync task completed")loop = asyncio.get_event_loop()
thread = threading.Thread(target=sync_task, args=(loop,))
thread.start()
thread.join()

使用 multiprocessingasyncio

import asyncio
import multiprocessingasync def async_task():print("Starting async task")await asyncio.sleep(2)print("Async task completed")def sync_task():loop = asyncio.new_event_loop()asyncio.set_event_loop(loop)loop.run_until_complete(async_task())if __name__ == "__main__":process = multiprocessing.Process(target=sync_task)process.start()process.join()
深入使用 trio

trio对异步编程提供了更友好的API,以及更加健壮的错误处理机制;它简化了异步编程的许多复杂性,特别是对于需要多个并发任务的场景:

基本使用
import trio
import asksasync def fetch(url):response = await asks.get(url)return response.textasync def main():urls = ['http://example.com', 'http://example.org', 'http://example.net']async with trio.open_nursery() as nursery:for url in urls:nursery.start_soon(fetch, url)trio.run(main)
高级功能:取消与超时

trio中,可以轻松地对任务进行取消和超时操作:

import trioasync def long_running_task():try:print("Task started")await trio.sleep(10)print("Task completed")except trio.Cancelled:print("Task was cancelled")async def main():async with trio.open_nursery() as nursery:nursery.start_soon(long_running_task)await trio.sleep(5)nursery.cancel_scope.cancel()trio.run(main)

异常处理与重试机制

import trio
import asksasync def fetch_with_retry(url, retries=3):for attempt in range(retries):try:response = await asks.get(url)return response.textexcept Exception as e:print(f"Attempt {attempt + 1} failed: {e}")await trio.sleep(2)raise Exception(f"Failed to fetch {url} after {retries} attempts")async def main():urls = ['http://example.com', 'http://example.org', 'http://example.net']async with trio.open_nursery() as nursery:for url in urls:nursery.start_soon(fetch_with_retry, url)trio.run(main)
深入使用 curio

curio 是另一个异步编程库,主要强调简单性和高性能,适用于需要低延迟和高吞吐量的场景:

基本使用
import curio
import httpxasync def fetch(url):async with httpx.AsyncClient() as client:response = await client.get(url)return response.textasync def main():urls = ['http://example.com', 'http://example.org', 'http://example.net']tasks = [fetch(url) for url in urls]results = await curio.gather(tasks)for result in results:print(result[:100])if __name__ == "__main__":curio.run(main)
高级功能:任务取消与超时

curio 和trio一样提供了强大的任务管理功能,其中也包括对任务取消和超时操作的处理:

import curioasync def long_running_task():try:print("Task started")await curio.sleep(10)print("Task completed")except curio.CancelledError:print("Task was cancelled")async def main():task = await curio.spawn(long_running_task)await curio.sleep(5)await task.cancel()if __name__ == "__main__":curio.run(main)

使用信号与事件进行任务同步

import curio![](https://files.mdnice.com/user/68804/a9f7fe95-2fc1-4c87-963a-cdbf8c34108b.jpg)async def producer(event):print("Producer sleeping")await curio.sleep(5)print("Producer setting event")await event.set()async def consumer(event):print("Consumer waiting for event")await event.wait()print("Consumer got event")async def main():event = curio.Event()await curio.gather(producer(event), consumer(event))if __name__ == "__main__":curio.run(main)

性能优化技巧

通过结合并发和异步编程技术,以及使用triocurio库,我们可以在处理大量I/O密集型任务时获得显著的性能提升,以下是我在工作中常用的一些性能优化技巧:

  1. 限制并发请求数量:使用信号量(semaphore)限制同时进行的请求数量,防止过多的请求导致系统资源枯竭;
  2. 分块处理任务:将任务划分为多个块,分别进行处理,避免一次性处理大量任务导致的性能问题;
  3. 使用连接池:复用连接,减少连接建立和销毁的开销;
  4. 合理设置超时时间:为每个请求设置合理的超时时间,防止由于某些请求超时导致整个任务的延迟;
  5. 异步I/O操作:尽量使用异步I/O操作,避免阻塞主线程。

结语

通过本文的介绍,我们深入学习了如何将并发编程与异步编程结合使用,以最大化程序的性能和效率。结合使用 threadingmultiprocessingasyncio 可以同时处理CPU密集型和I/O密集型任务,提升程序整体性能,希望这些技巧能帮助你在实际项目中编写出高效、稳定的代码!
如果你对计算机相关技术有更多的兴趣,想要持续的探索,请关注我的公众号哟!

相关文章:

深入理解Python中的并发与异步的结合使用

​ 在上一篇文章中,我们讨论了异步编程中的性能优化技巧,并简单介绍了trio和curio库。今天,我们将深入探讨如何将并发编程与异步编程结合使用,并详细讲解如何利用trio和curio库优化异步编程中的性能。 文章目录 并发与异步编程的区…...

如何将 ChatGPT 集成到你的应用中

在当今快速发展的技术环境中,将人工智能聊天解决方案集成到你的应用程序中可以显著提升用户体验和参与度。OpenAI 的 ChatGPT 以其对话能力和高级语言理解而闻名,对于希望在其应用程序中实现智能聊天功能的开发人员来说是一个绝佳的选择。那我们今天就来…...

在 Swift 中,UILabel添加点击事件的方法

在 Swift 中,可以使用 UITapGestureRecognizer 给 UILabel 添加点击事件。以下是一个详细的步骤和示例代码: 1. 创建 UILabel 并添加到视图 在 Storyboard 或代码中创建一个 UILabel 并将其添加到视图中。 2. 启用 UILabel 的用户交互 默认情况下&am…...

indexedDB---掌握浏览器内建数据库的基本用法

1.认识indexedDB IndexedDB 是一个浏览器内建的数据库,它可以存放对象格式的数据,类似本地存储localstore,但是相比localStore 10MB的存储量,indexedDB可存储的数据量远超过这个数值,具体是多少呢? 默认情…...

【css】如何修改input选中历史选项后,自动填充的蓝色背景色

自动填充前: 自动填充后: 解决办法 方法一:设置背景透明(通过拉长过渡时间,和延迟过渡开始时间,掩盖input自动填充背景颜色) PS:注意,这个过渡效果会在你的delay tim…...

红队内网攻防渗透:内网渗透之内网对抗:网络通讯篇防火墙组策略入站和出站规则单层双层C2正反向上线解决方案

红队内网攻防渗透 1. 内网网络通讯1.1 防火墙策略-入站规则&出站规则&自定义1.1.1 防火墙默认入站&出站策略1.1.2 防火墙自定义入站&出站策略1.1.3 内网域防火墙同步策略1.2 防火墙限制1.2.1 防火墙限制端口1.2.2 防火墙限制协议1.2.2.1 防火墙协议入站限制1.2…...

linux 查看进程启动方式

目录 如果是systemd管理的服务怎么快速找到对应的服务器呢 什么是CGroup 查找进程对应的systemd服务 方法一:查看 /proc//cgroup 文件 方法二:使用 ps 命令结合 --cgroup 选项 方法三:systemd-cgls 关于 system.slice 与 user.slice …...

基于Java实训中心管理系统设计和实现(源码+LW+调试文档+讲解等)

💗博主介绍:✌全网粉丝10W,CSDN作者、博客专家、全栈领域优质创作者,博客之星、平台优质作者、专注于Java、小程序技术领域和毕业项目实战✌💗 🌟文末获取源码数据库🌟 感兴趣的可以先收藏起来,…...

第2章 Android应用的界面编程

🌈个人主页:小新_- 🎈个人座右铭:“成功者不是从不失败的人,而是从不放弃的人!”🎈 🎁欢迎各位→点赞👍 收藏⭐️ 留言📝 🏆所属专栏&#xff1…...

springboot学习-图灵课堂-最详细学习

springboot-repeat springBoot学习代码说明为什么java -jar springJar包后项目就可以启动 配置文件介绍 springBoot学习 依赖引入 <properties><project.build.sourceEncoding>UTF-8</project.build.sourceEncoding><maven.compiler.target>8</mav…...

Total CAD Converter与Total Excel Converter软件分享

1.软件介绍 Total CAD Converter Total CAD Converter 是一款功能强大的工具&#xff0c;能够将 CAD 文件转换为多种格式&#xff0c;如 PDF、TIFF、JPEG、BMP、WMF、PNG、DXF、BMP、CGM、HPGL、SVG、PS 和 SWF 等。其支持的源格式丰富多样&#xff0c;包括 dxf、dwg、dwf、d…...

【2024最新华为OD-C/D卷试题汇总】[支持在线评测] 启动多任务排序(200分) - 三语言AC题解(Python/Java/Cpp)

🍭 大家好这里是清隆学长 ,一枚热爱算法的程序员 ✨ 本系列打算持续跟新华为OD-C/D卷的三语言AC题解 💻 ACM银牌🥈| 多次AK大厂笔试 | 编程一对一辅导 👏 感谢大家的订阅➕ 和 喜欢💗 📎在线评测链接 启动多任务排序(200分) 🌍 评测功能需要订阅专栏后私信联系…...

【会议征稿,JPCS出版】第三届电力系统与能源技术国际学术会议(ICPSET 2024,7月5-7)

第三届电力系统与能源技术国际学术会议&#xff08;ICPSET 2024&#xff09;将于2024年7月5-7日在杭州举办。由浙江水利水电学院电机产业学院主办&#xff0c;AEIC学术交流中心承办&#xff0c;湖州市南浔创新研究院、南浔区科技局&#xff08;科协&#xff09;协办 。会议主要…...

【机器学习300问】118、循环神经网络(RNN)的基本结构是怎样的?

将讲解循环神经网络RNN之前&#xff0c;我先抛出几个疑问&#xff1a;为什么发明循环神经网络&#xff1f;它的出现背景是怎样的&#xff1f;这些问题可以帮助我们更好的去理解RNN。下面我来逐一解答。 一、循环神经网络诞生的背景 循环神经网络&#xff08;RNN&#xff09;的…...

loveqq-framework 和 thymeleaf 整合遇到的 th:field 的坑,原来只有 spring 下才有效

相信大家在使用 thymeleaf 的时候&#xff0c;绝大部分都是和 springboot 一块儿使用的&#xff0c;所以 th:field 属性用的很舒服。 但实际上&#xff0c;th:field 只有在 spring 环境下下有用&#xff0c;单独的 thymeleaf 是不支持的&#xff01; 为什么我知道呢&#xff…...

hugging face:大模型时代的github介绍

1. Hugging Face是什么&#xff1a; Hugging Face大模型时代的“github”&#xff0c;很多人有个这样的认知&#xff0c;但是我觉得不完全准确&#xff0c;他们相似的地方在于资源丰富&#xff0c;github有各种各样的软件代码和示例&#xff0c;但是它不是系统的&#xff0c;没…...

如何快速绘制logistic回归预测模型的ROC曲线?

临床预测模型&#xff0c;也是临床统计分析的一个大类&#xff0c;除了前期构建模型&#xff0c;还要对模型的预测能力、区分度、校准度、临床获益等方面展开评价&#xff0c;确保模型是有效的&#xff01; 其中评价模型的好坏主要方面还是要看区分度和校准度&#xff0c;而区分…...

实现具有多个实现类的接口并为每个实现类定义一个名字的方法

在Java中&#xff0c;实现具有多个实现类的接口并为每个实现类定义一个名字的方法&#xff0c;可以通过使用工厂模式或服务定位器模式来完成。以下是使用工厂模式的一个示例&#xff1a; 定义接口和实现类 首先&#xff0c;定义一个接口和多个实现类&#xff1a; // 接口 publ…...

Linux解压缩命令

文章目录 前言1. tar - 打包和压缩文件2. gzip - 压缩文件3. gunzip - 解压缩gzip文件4. bzip2 - 压缩文件5. unzip - 解压缩zip文件6. zip - 压缩文件为zip格式7. 7z - 7-Zip压缩工具8. unrar - 解压缩RAR文件 前言 解压缩文件在Linux中是常见的任务&#xff0c;以下是一些常…...

如何在 Ubuntu 14.04 上使用 Iptables 实现基本防火墙模板

前些天发现了一个巨牛的人工智能学习网站&#xff0c;通俗易懂&#xff0c;风趣幽默&#xff0c;忍不住分享一下给大家。点击跳转到网站。 简介 实施防火墙是保护服务器的重要步骤。其中很大一部分是决定强制执行对网络流量的限制的个别规则和策略。像 iptables 这样的防火墙…...

【大模型RAG】拍照搜题技术架构速览:三层管道、两级检索、兜底大模型

摘要 拍照搜题系统采用“三层管道&#xff08;多模态 OCR → 语义检索 → 答案渲染&#xff09;、两级检索&#xff08;倒排 BM25 向量 HNSW&#xff09;并以大语言模型兜底”的整体框架&#xff1a; 多模态 OCR 层 将题目图片经过超分、去噪、倾斜校正后&#xff0c;分别用…...

基于FPGA的PID算法学习———实现PID比例控制算法

基于FPGA的PID算法学习 前言一、PID算法分析二、PID仿真分析1. PID代码2.PI代码3.P代码4.顶层5.测试文件6.仿真波形 总结 前言 学习内容&#xff1a;参考网站&#xff1a; PID算法控制 PID即&#xff1a;Proportional&#xff08;比例&#xff09;、Integral&#xff08;积分&…...

unix/linux,sudo,其发展历程详细时间线、由来、历史背景

sudo 的诞生和演化,本身就是一部 Unix/Linux 系统管理哲学变迁的微缩史。来,让我们拨开时间的迷雾,一同探寻 sudo 那波澜壮阔(也颇为实用主义)的发展历程。 历史背景:su的时代与困境 ( 20 世纪 70 年代 - 80 年代初) 在 sudo 出现之前,Unix 系统管理员和需要特权操作的…...

Typeerror: cannot read properties of undefined (reading ‘XXX‘)

最近需要在离线机器上运行软件&#xff0c;所以得把软件用docker打包起来&#xff0c;大部分功能都没问题&#xff0c;出了一个奇怪的事情。同样的代码&#xff0c;在本机上用vscode可以运行起来&#xff0c;但是打包之后在docker里出现了问题。使用的是dialog组件&#xff0c;…...

在QWebEngineView上实现鼠标、触摸等事件捕获的解决方案

这个问题我看其他博主也写了&#xff0c;要么要会员、要么写的乱七八糟。这里我整理一下&#xff0c;把问题说清楚并且给出代码&#xff0c;拿去用就行&#xff0c;照着葫芦画瓢。 问题 在继承QWebEngineView后&#xff0c;重写mousePressEvent或event函数无法捕获鼠标按下事…...

Java + Spring Boot + Mybatis 实现批量插入

在 Java 中使用 Spring Boot 和 MyBatis 实现批量插入可以通过以下步骤完成。这里提供两种常用方法&#xff1a;使用 MyBatis 的 <foreach> 标签和批处理模式&#xff08;ExecutorType.BATCH&#xff09;。 方法一&#xff1a;使用 XML 的 <foreach> 标签&#xff…...

【JavaSE】多线程基础学习笔记

多线程基础 -线程相关概念 程序&#xff08;Program&#xff09; 是为完成特定任务、用某种语言编写的一组指令的集合简单的说:就是我们写的代码 进程 进程是指运行中的程序&#xff0c;比如我们使用QQ&#xff0c;就启动了一个进程&#xff0c;操作系统就会为该进程分配内存…...

【网络安全】开源系统getshell漏洞挖掘

审计过程&#xff1a; 在入口文件admin/index.php中&#xff1a; 用户可以通过m,c,a等参数控制加载的文件和方法&#xff0c;在app/system/entrance.php中存在重点代码&#xff1a; 当M_TYPE system并且M_MODULE include时&#xff0c;会设置常量PATH_OWN_FILE为PATH_APP.M_T…...

Python 实现 Web 静态服务器(HTTP 协议)

目录 一、在本地启动 HTTP 服务器1. Windows 下安装 node.js1&#xff09;下载安装包2&#xff09;配置环境变量3&#xff09;安装镜像4&#xff09;node.js 的常用命令 2. 安装 http-server 服务3. 使用 http-server 开启服务1&#xff09;使用 http-server2&#xff09;详解 …...

论文阅读:LLM4Drive: A Survey of Large Language Models for Autonomous Driving

地址&#xff1a;LLM4Drive: A Survey of Large Language Models for Autonomous Driving 摘要翻译 自动驾驶技术作为推动交通和城市出行变革的催化剂&#xff0c;正从基于规则的系统向数据驱动策略转变。传统的模块化系统受限于级联模块间的累积误差和缺乏灵活性的预设规则。…...