深入理解Python中的并发与异步的结合使用
在上一篇文章中,我们讨论了异步编程中的性能优化技巧,并简单介绍了trio
和curio
库。今天,我们将深入探讨如何将并发编程与异步编程结合使用,并详细讲解如何利用trio
和curio
库优化异步编程中的性能。
文章目录
- 并发与异步编程的区别与联系
- 并发编程与异步编程的优缺点
- 并发编程
- 异步编程
- 如何在同一个程序中同时使用 `threading`、`multiprocessing` 和 `asyncio`
- 使用 `threading` 和 `asyncio`
- 深入使用 `trio` 库
- 基本使用
- 高级功能:取消与超时
- 深入使用 `curio` 库
- 基本使用
- 高级功能:任务取消与超时
- 性能优化技巧
- 结语
并发与异步编程的区别与联系
并发编程和异步编程都是处理多任务的有效手段,但它们的实现方式和适用场景有所不同:
- 并发编程:通过线程或进程来同时执行多个任务,适用于CPU密集型任务;
- 异步编程:通过事件循环和协程来调度任务,适用于I/O密集型任务。
结合使用并发和异步编程,可以同时处理CPU密集型和I/O密集型任务,提升程序整体性能。
并发编程与异步编程的优缺点
并发编程
- 优点:
- 可以充分利用多核CPU的优势,提高程序的执行效率;
- 适用于需要大量计算的任务,例如数据处理、图像处理等。
- 缺点:
- 线程和进程的管理和调度较为复杂,需要处理同步、锁等问题;
- 创建和销毁线程或进程会有一定的开销。
异步编程
- 优点:
- 适用于I/O密集型任务,可以在等待I/O操作完成时执行其他任务,提高资源利用率;
- 代码更加简洁,逻辑清晰。
- 缺点:
- 仅能在单线程中运行,不能利用多核CPU的优势;
- 对于CPU密集型任务效果不佳。
如何在同一个程序中同时使用 threading
、multiprocessing
和 asyncio
在同一个程序中,我们可以利用 threading
和 multiprocessing
提供并发能力,同时使用 asyncio
实现异步I/O操作:
使用 threading
和 asyncio
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()
使用 multiprocessing
和 asyncio
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)
性能优化技巧
通过结合并发和异步编程技术,以及使用trio
和curio
库,我们可以在处理大量I/O密集型任务时获得显著的性能提升,以下是我在工作中常用的一些性能优化技巧:
- 限制并发请求数量:使用信号量(semaphore)限制同时进行的请求数量,防止过多的请求导致系统资源枯竭;
- 分块处理任务:将任务划分为多个块,分别进行处理,避免一次性处理大量任务导致的性能问题;
- 使用连接池:复用连接,减少连接建立和销毁的开销;
- 合理设置超时时间:为每个请求设置合理的超时时间,防止由于某些请求超时导致整个任务的延迟;
- 异步I/O操作:尽量使用异步I/O操作,避免阻塞主线程。
结语
通过本文的介绍,我们深入学习了如何将并发编程与异步编程结合使用,以最大化程序的性能和效率。结合使用 threading
、multiprocessing
和 asyncio
可以同时处理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应用的界面编程
🌈个人主页:小新_- 🎈个人座右铭:“成功者不是从不失败的人,而是从不放弃的人!”🎈 🎁欢迎各位→点赞👍 收藏⭐️ 留言📝 🏆所属专栏࿱…...
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 是一款功能强大的工具,能够将 CAD 文件转换为多种格式,如 PDF、TIFF、JPEG、BMP、WMF、PNG、DXF、BMP、CGM、HPGL、SVG、PS 和 SWF 等。其支持的源格式丰富多样,包括 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)
第三届电力系统与能源技术国际学术会议(ICPSET 2024)将于2024年7月5-7日在杭州举办。由浙江水利水电学院电机产业学院主办,AEIC学术交流中心承办,湖州市南浔创新研究院、南浔区科技局(科协)协办 。会议主要…...
【机器学习300问】118、循环神经网络(RNN)的基本结构是怎样的?
将讲解循环神经网络RNN之前,我先抛出几个疑问:为什么发明循环神经网络?它的出现背景是怎样的?这些问题可以帮助我们更好的去理解RNN。下面我来逐一解答。 一、循环神经网络诞生的背景 循环神经网络(RNN)的…...
loveqq-framework 和 thymeleaf 整合遇到的 th:field 的坑,原来只有 spring 下才有效
相信大家在使用 thymeleaf 的时候,绝大部分都是和 springboot 一块儿使用的,所以 th:field 属性用的很舒服。 但实际上,th:field 只有在 spring 环境下下有用,单独的 thymeleaf 是不支持的! 为什么我知道呢ÿ…...
hugging face:大模型时代的github介绍
1. Hugging Face是什么: Hugging Face大模型时代的“github”,很多人有个这样的认知,但是我觉得不完全准确,他们相似的地方在于资源丰富,github有各种各样的软件代码和示例,但是它不是系统的,没…...
如何快速绘制logistic回归预测模型的ROC曲线?
临床预测模型,也是临床统计分析的一个大类,除了前期构建模型,还要对模型的预测能力、区分度、校准度、临床获益等方面展开评价,确保模型是有效的! 其中评价模型的好坏主要方面还是要看区分度和校准度,而区分…...
实现具有多个实现类的接口并为每个实现类定义一个名字的方法
在Java中,实现具有多个实现类的接口并为每个实现类定义一个名字的方法,可以通过使用工厂模式或服务定位器模式来完成。以下是使用工厂模式的一个示例: 定义接口和实现类 首先,定义一个接口和多个实现类: // 接口 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中是常见的任务,以下是一些常…...
如何在 Ubuntu 14.04 上使用 Iptables 实现基本防火墙模板
前些天发现了一个巨牛的人工智能学习网站,通俗易懂,风趣幽默,忍不住分享一下给大家。点击跳转到网站。 简介 实施防火墙是保护服务器的重要步骤。其中很大一部分是决定强制执行对网络流量的限制的个别规则和策略。像 iptables 这样的防火墙…...
jasypt对yml文件进行加密解密
目录 0.背景 1.依赖 2.yml文件 3.加密操作 0.背景 在日常开发中,我们一般会把账号密码以及一些用到的各种第三方服务的Access_Key都放入yml文件中,这时就有必要对yml文件进行加密处理了, jasypt是一款简单的对yml加密的工具 1.依赖 &l…...
vue3-openlayers 使用tianditu,wmts和xyz等source加载天地图切片服务
本篇介绍一下使用vue3-openlayers加载天地图切片,三种方法: 使用tianditu(ol-source-tianditu内部实现其实用的wmts)使用wmts(ol-source-wmts)使用xyz(ol-source-xyz) 1 需求 vue…...
npm、yarn、pnpm 最新国内镜像源设置和常见问题解决
1. npm 设置国内镜像源 1.1 镜像源概述 镜像源是软件包管理工具用来下载和安装软件包的服务器地址。由于网络原因,直接使用官方源可能会导致速度慢或连接失败的问题。国内镜像源可以提供更快的访问速度和更稳定的连接。 1.2 镜像源的选择 国内有许多可用的npm镜…...
Qt Object:智能即时聊天室项目
目录 1.项目介绍 2.设计思路 3.Pro文件配置 4.项目演示 5.项目开源 项目介绍 智能即时聊天室系统(AIChatProject)是一个高效、灵活的即时通讯解决方案。它融合了百度的开源大型语言模型——文心一言,通过API接口实现深度集成。系统专为聊天和…...
php,python aes加密反解
1. python版本 import base64 from Crypto.Cipher import AES from Crypto.Util.Padding import pad, unpadclass AESUtilCBC:def __init__(self, key, iv):self.key key.encode(utf-8)self.iv iv.encode(utf-8)self.pad_length AES.block_sizedef encrypt(self, data):try…...
基于Java学生选课管理系统设计和实现(源码+LW+调试文档+讲解等)
💗博主介绍:✌全网粉丝10W,CSDN作者、博客专家、全栈领域优质创作者,博客之星、平台优质作者、专注于Java、小程序技术领域和毕业项目实战✌💗 🌟文末获取源码数据库🌟 感兴趣的可以先收藏起来,…...
阅读笔记——《Large Language Model guided Protocol Fuzzing》
【参考文献】Meng R, Mirchev M, Bhme M, et al. Large language model guided protocol fuzzing[C]//Proceedings of the 31st Annual Network and Distributed System Security Symposium (NDSS). 2024.(CCF A类会议)【注】本文仅为作者个人学习笔记&a…...
C#委托:事件驱动编程的基石
目录 了解委托 委托使用的基本步骤 声明委托(定义一个函数的原型:返回值 参数类型和个数) 根据委托定义的函数原型编写需要的方法 创建委托对象,关联“具体方法” 通过委托调用方法,而不是直接使用方法 委托对象所关联的方…...
Git的下载安装及可视化工具小乌龟
一、 Git 的下载 第1步:下载Git,下载地址:Git for Windows 这个就需要去 Git 官网下载对应系统的软件了,下载地址为 git-scm.com或者gitforwindows.org,或者阿里镜像(感谢评论区的星悸迷航同学&#…...
【面试实战】# 并发编程之线程池配置实战
1.先了解线程池的几个参数含义 corePoolSize (核心线程池大小): 作用: 指定了线程池维护的核心线程数量,即使这些线程处于空闲状态,它们也不会被回收。用途: 核心线程用于处理长期的任务,保持最低的线程数量,以减少线程的创建和…...
Pytest 读取excel文件参数化应用
本文是基于Pytest框架,读取excel中的文件,传入页面表单中,并做相应的断言实现。 1、编辑媒体需求 首先明确一下需求,我们需要对媒体的表单数据进行编辑,步骤如下: 具体表单如下图所示 1、登录 2、点击我…...
qt 一个可以拖拽的矩形
1.概要 2.代码 2.1 mycotrl.h #ifndef MYCOTRL_H #define MYCOTRL_H#include <QWidget> #include <QMouseEvent>class MyCotrl: public QWidget {Q_OBJECT public://MyCotrl();MyCotrl(QWidget *parent nullptr); protected:void paintEvent(QPaintEvent *even…...
C# 启动exe 程序
(1) publicbool Start () System.Diagnostics.Process process new System.Diagnostics.Process(); process.StartInfo.FileName "iexplore.exe"; //IE浏览器,可以更换 process.StartInfo.Arguments "http://www.baidu.com"; process.…...
Netty中的Reactor模型实现
Netty版本:4.1.17 Reactor模型是Doug Lea在《Scalable IO in Java》提出的,主要是针对NIO的。 其中的主从Reactor模式在Netty中的配置如下: EventLoopGroup bossGroup new NioEventLoopGroup(1); EventLoopGroup workerGroup new NioEv…...
dll丢失应该怎么解决,总结5种解决DLL丢失问题的方法
在数字时代,我们与计算机的每一天都密不可分。然而,就像所有技术产品一样,我们的计算设备也时不时地会出现一些问题,让人头疼不已。就在上周,我遭遇了一个令人崩溃的技术挑战——DLL文件丢失。这个看似微不足道的小问题…...
dial tcp 10.96.0.1:443: connect: no route to host
1、创建Pod一直不成功,执行kubectl describe pod runtime-java-c8b465b98-47m82 查看报错 Warning FailedCreatePodSandBox 2m17s kubelet Failed to create pod sandbox: rpc error: code Unknown desc failed to setup network for…...
VScode创建ROS项目 ROS集成开发环境
ROS使用VScode创建项目步骤 1.创建ROS工作空间2.启动VScode3.VScode编译ROS4.创建ROS功能包C语言开发Python语言开发 本文章介绍了如何在Ubuntu18.04系统下搭建VScode 的ROS项目 搭建项目分为一下几个步骤: 1.创建ROS工作空间 创建一个demo的ROS工作空间࿰…...
nodejs从基础到实战学习笔记-nodejs简介
一、Node.js简介 • Node.js是一个能够在服务器端运行JavaScript的开放源代码、跨平台JavaScript运行环境。 • Node采用Google开发的V8引擎运行js代码,使用事件驱动、非阻塞和异步I/O模型等技术来提高性能,可优化应用程序的传输量和规模。 1.1 特性 …...
2024年最新版------二进制安装部署Kubernetes(K8S)集群
Kubernetes二进制集群部署 文章目录 Kubernetes二进制集群部署资源列表基础环境一、环境准备1.1、绑定映射关系1.2、所有主机安装Docker1.3、所有主机设置iptables防火墙 二、生成通信加密证书2.1、master上成功CA证书2.2.1、创建证书存放位置并安装证书生成工具2.2.2、拷贝证书…...
【mysql】关键词搜索实现
关键词搜索实现两种方式 -- 方式1 模糊匹配搜索 -- 场景一:搜索出来地址内包含‘李’和‘中国’的 select * from tn_md_cust_link where address like concat (%李%) or address like concat (%中国%) -- 场景二:搜索地址或者名称包含 ‘181’ 的 …...
Python面试十问2
一、如何使用列表创建⼀个DataFrame # 导入pandas库 import pandas as pd# 创建一个列表,其中包含数据 data [[A, 1], [B, 2], [C, 3]]# 使用pandas的DataFrame()函数将列表转换为DataFrame df pd.DataFrame(data, columns[Letter, Number]) # 列名# 显示创建的…...
C# OpenCvSharp 图像处理函数-颜色通道-cvtColor
使用 OpenCvSharp 中的 cvtColor 函数进行图像颜色转换 在图像处理领域,颜色空间转换是一个非常常见的操作。OpenCvSharp 提供了一个强大的函数 cvtColor 来处理这类转换。本文将详细介绍 cvtColor 函数的使用方法,并通过具体的示例演示如何在实际项目中应用这些知识。 函数…...
总结之LangChain(三)——模型IO缓存
一、聊天模型缓存 LangChain为聊天模型提供了一个可选的缓存层。这有两个好处: 如果您经常多次请求相同的完成结果,它可以通过减少您对LLM提供程序的API调用次数来帮您节省费用。 它可以通过减少您对LLM提供程序的API调用次数来加快您的应用程序速度。…...
判断一个Java服务是不是GateWay
方法 直接在对应服务的url后变加上后缀/actuator/gateway/routes,看是否会返回Gateway的路由信息。 如果返回了GateWay的路由列表,则该服务为Gateway服务。...
三次插值曲线--插值技术
三次插值曲线 1.1.三次样条曲线 三次样条曲线的基本思想是,在给定的一系列点(称为控制点或数据点)之间,通过一系列三次多项式曲线段来拟合这些点,使得整个曲线既平滑又准确地通过所有控制点。 1.1.1.数学定义 给定…...
python循环结构
1.while 循环 语句: while 循环条件表达式: 代码块 else: 代码块 小练: 设计一百以内的偶数相加 n 0 while n < 100:n 1if n % 2 0 :print(n) 判断是不是闰年(四年一润和百年不润,或者四百年一润&am…...
深入理解Netty的Pipeline机制:原理与实践详解
深入理解Netty的Pipeline机制:原理与实践详解 Netty是一个基于Java的高性能异步事件驱动的网络应用框架,广泛应用于高并发网络编程。(学习netty请参考:深入浅出Netty:高性能网络应用框架的原理与实践)Nett…...
直方图均衡化示例
禹晶、肖创柏、廖庆敏《数字图像处理(面向新工科的电工电子信息基础课程系列教材)》 图3-17...
私域电商新纪元:消费增值模式的创新与成功实践
大家好,我是吴军,很高兴能够与您分享私域电商领域的魅力与机遇。今天,我将为大家呈现一个令人瞩目的成功案例,这个案例充分展现了私域电商的巨大潜力和无限可能。 在短短一个月的时间里,我们的客户成功实现了业绩的飞跃…...
Java——IO流(一)-(6/8):字节流-FileInputStream 每次读取多个字节(示例演示)、一次读取完全部字节(方式一、方式二,注意事项)
目录 文件字节输入流:每次读取多个字节 实例演示 注意事项 文件字节输入流:一次读取完全部字节 方式一 方式二 注意事项 文件字节输入流:每次读取多个字节 用到之前介绍过的常用方法: 实例演示 需求:用每次读取…...