使用Python进行并发和并行编程:提高效率的秘诀

使用Python进行并发和并行编程:提高效率的秘诀

​ 大家好,今天我们来聊聊如何使用Python进行并发和并行编程,以提升数据处理的效率;在之前的文章中,我们探讨了Python的函数式编程和数据流处理。今天,我们将进一步讨论如何利用Python中的并发和并行编程来优化我们的程序性能。

文章目录

    • 使用Python进行并发和并行编程:提高效率的秘诀
      • 并发和并行的区别
      • Python中的并发编程
        • 使用`threading`模块
        • 线程安全和共享数据
      • Python中的并行编程
        • 使用`multiprocessing`模块
        • 进程间通信
      • 异步编程
        • 使用`asyncio`模块
        • 异步I/O操作
      • 实际应用场景
        • 案例研究:并发与并行在机器学习中的应用
      • 最佳实践和注意事项
      • 结语

并发和并行的区别

首先,让我们了解一下并发和并行的区别:

  • 并发:指在同一时间段内管理多个任务,任务之间可以交替执行。例如,在单核CPU上可以通过时间片轮转实现并发、
  • 并行:指在同一时刻执行多个任务,通常需要多核CPU支持。例如,在四核CPU上可以同时运行四个任务。

并发和并行虽然听起来类似,但其应用场景和实现方式有所不同。理解这两者的区别有助于我们在不同场景下选择合适的编程方法。

Python中的并发编程

​ Python中的并发编程可以通过threading模块来实现,threading模块提供了一个高层次的接口,允许我们轻松地创建和管理线程,线程是操作系统能够进行独立调度和分配的基本单位。

使用threading模块

​ 以下是一个使用threading模块的简单示例,演示如何创建和启动多个线程来处理并发任务:

import threading
import timedef worker(name):print(f'{name} 开始工作')time.sleep(2)print(f'{name} 工作结束')threads = []
for i in range(5):thread = threading.Thread(target=worker, args=(f'线程 {i+1}',))threads.append(thread)thread.start()for thread in threads:thread.join()print('所有线程工作结束')

​ 上面的示例创建了5个线程,每个线程都会执行worker函数,并在函数中休眠2秒钟。在实际应用中,并发编程可以用于处理多个I/O操作,例如同时读取多个文件或处理多个网络请求,从而提高整体处理效率。值得注意的是,Python的全局解释器锁(GIL)限制了多线程在CPU密集型任务中的性能提升,但对于I/O密集型任务,多线程仍然是非常有效的解决方案。

线程安全和共享数据

​ 在多线程编程中,共享数据可能会导致竞争条件(race condition)和数据不一致的问题,为了避免这些问题,可以使用线程锁(lock)来确保同一时间只有一个线程访问共享资源:

import threadinglock = threading.Lock()
counter = 0def increment_counter():global counterwith lock:counter += 1threads = [threading.Thread(target=increment_counter) for _ in range(100)]
for thread in threads:thread.start()
for thread in threads:thread.join()print(f'最终计数值:{counter}')

Python中的并行编程

​ 对于CPU密集型任务,使用multiprocessing模块可以更好地利用多核CPU的优势,multiprocessing模块允许我们创建多个进程,每个进程独立运行在不同的CPU核心上。

使用multiprocessing模块

​ 以下是一个使用multiprocessing模块的示例,演示如何创建和启动多个进程来处理并行任务:

import multiprocessing
import timedef worker(name):print(f'{name} 开始工作')time.sleep(2)print(f'{name} 工作结束')processes = []
for i in range(5):process = multiprocessing.Process(target=worker, args=(f'进程 {i+1}',))processes.append(process)process.start()for process in processes:process.join()print('所有进程工作结束')

​ 上面的示例创建了5个进程,每个进程都会执行worker函数,并在函数中休眠2秒钟;并行编程特别适合处理需要大量计算的任务,例如大数据处理、科学计算和图像处理等领域。

进程间通信

​ 在多进程编程中,进程之间的通信(IPC)是一个重要的课题,multiprocessing模块提供了多种IPC机制,如管道(pipe)和队列(queue),使得进程之间能够安全地交换数据:

import multiprocessingdef worker(queue):queue.put('消息来自子进程')if __name__ == '__main__':queue = multiprocessing.Queue()process = multiprocessing.Process(target=worker, args=(queue,))process.start()print(queue.get())process.join()

异步编程

​ 对于I/O密集型任务,异步编程可以显著提高效率,Python的asyncio模块提供了对异步编程的支持,使我们能够编写高效的异步代码。

使用asyncio模块

​ 以下是一个使用asyncio模块的示例,演示如何使用异步函数处理网络请求:

import asyncioasync def worker(name):print(f'{name} 开始工作')await asyncio.sleep(2)print(f'{name} 工作结束')async def main():tasks = []for i in range(5):task = asyncio.create_task(worker(f'任务 {i+1}'))tasks.append(task)await asyncio.gather(*tasks)print('所有任务工作结束')asyncio.run(main())

​ 上面的示例创建了5个异步任务,每个任务都会执行worker函数,并在函数中异步休眠2秒钟;异步编程非常适合处理需要等待的操作,例如网络请求、数据库查询和文件读写等。

异步I/O操作

asyncio模块的强大之处在于能够处理大量并发I/O操作。以下示例展示了如何使用asyncio进行并发HTTP请求:

import asyncio
import aiohttpasync def fetch(session, url):async with session.get(url) as response:return await response.text()async def main():async with aiohttp.ClientSession() as session:tasks = [fetch(session, f'http://example.com/{i}') for i in range(10)]responses = await asyncio.gather(*tasks)for response in responses:print(response)asyncio.run(main())

​ 上面的示例使用aiohttp库进行异步HTTP请求,同时处理多个URL,提高了网络请求的效率。

实际应用场景

并发和并行编程在许多实际应用中都非常有用,以下是几个例子:

  • 网页爬虫:可以使用多线程或异步编程来加速网页抓取过程。例如,Scrapy就是一个基于异步编程的高效爬虫框架。
  • 数据分析:可以使用多进程并行处理大数据集,提高数据分析的速度。例如,Pandas可以与multiprocessing结合使用,实现并行数据处理。
  • 机器学习:可以使用多进程并行训练多个模型或并行处理大规模数据。例如,scikit-learn支持并行训练多个模型,提高训练速度。
案例研究:并发与并行在机器学习中的应用

​ 在机器学习项目中,模型训练通常是一个计算密集型任务。使用多进程并行处理可以显著减少训练时间,以下示例展示了如何使用joblib库实现并行模型训练:

from joblib import Parallel, delayed
from sklearn.datasets import make_classification
from sklearn.ensemble import RandomForestClassifier
from sklearn.model_selection import cross_val_scoredef train_model(seed):X, y = make_classification(n_samples=1000, n_features=20, random_state=seed)model = RandomForestClassifier(random_state=seed)scores = cross_val_score(model, X, y, cv=5)return scores.mean()seeds = range(10)
results = Parallel(n_jobs=-1)(delayed(train_model)(seed) for seed in seeds)
print(results)

​ 示例使用joblib库的Paralleldelayed函数来并行化模型训练,提高了训练速度。

最佳实践和注意事项

在使用并发和并行编程时,以下是一些最佳实践和注意事项:

  • 避免共享状态:尽量避免在线程或进程之间共享状态,以减少竞争条件和数据不一致的问题。可以使用线程安全的队列(例如queue.Queue)或进程安全的队列(例如multiprocessing.Queue)来进行数据交换。
  • 使用线程池和进程池:使用concurrent.futures模块中的ThreadPoolExecutorProcessPoolExecutor来管理线程和进程池,提高代码的可维护性和效率。例如:
from concurrent.futures import ThreadPoolExecutor, ProcessPoolExecutordef worker(name):print(f'{name} 开始工作')time.sleep(2)print(f'{name} 工作结束')# 使用线程池
with ThreadPoolExecutor(max_workers=5) as executor:for i in range(5):executor.submit(worker, f'线程 {i+1}')# 使用进程池
with ProcessPoolExecutor(max_workers=5) as executor:for i in range5:executor.submit(worker, f'进程 {i+1}')
  • 异常处理:在并发和并行编程中,添加适当的异常处理机制,以应对潜在的错误和异常。例如,可以在任务函数中添加try-except块,并记录异常日志。
  • 优化性能:在处理大规模数据时,注意优化性能,避免不必要的计算和资源浪费。例如,可以使用NumPy等高效的数值计算库,提高数据处理效率。

结语

​ 通过学习并应用Python中的并发和并行编程技术,我们可以显著提升程序的效率和性能。希望大家在实际项目中多多尝试使用这些技术,提升代码的运行效率。如果你有任何问题或想法,欢迎在评论区留言。Happy coding!
在这里插入图片描述

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/web/34711.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

查询SQL 人大金仓 与MySQL的区别

查询SQL 人大金仓 与MySQL的区别&#xff0c;以若依为例 最常见 时间范围 1.人大金仓 Kingbase <select id"selectUserListByOrgIds" parameterType"SysUser" resultMap"SysUserResult">select u.user_id, u.dept_id, u.nick_name,u.tj_…

力扣2748.美丽下标对的数目

力扣2748.美丽下标对的数目 朴素思路 二重循环模拟 class Solution {public:int gcd(int a,int b){return b ? gcd(b,a%b):a;}int countBeautifulPairs(vector<int>& nums) {int res0;for(int i0;i<nums.size() - 1;i)for(int ji1;j<nums.size();j){strin…

C++用Crow实现一个简单的Web程序,实现动态页面,向页面中输入数据并展示

Crow是一个轻量级、快速的C微框架&#xff0c;用于构建Web应用程序和RESTful API。 将处理前端页面的POST请求以添加数据的逻辑添加到 /submit 路由中&#xff0c;并添加了一个新的路由 / 用于返回包含输入框、按钮和表格的完整页面。当用户向表格添加数据时&#xff0c;JavaS…

SpringAOP执行流程——从源码画流程图

文章目录 了解ProxyFactory入门操作添加多个Advice的执行顺序关于异常Advice关于proceed()方法指定方法才进行增强逻辑 创建代理对象的其他方式ProxyFactoryBeanBeanNameAutoProxyCreatorDefaultAdvisorAutoProxyCreator 对SpringAOP的理解TargetSourceProxyFactory选择JDK/CJL…

【教学类-64-05】20240625彩棒鱼骨图(二)AB排列 6.5*1CM 6选2根 30种

背景需求&#xff1a; 【教学类-64-04】20240619彩棒鱼骨图&#xff08;一&#xff09;6.5*1CM 6根棒子720种-CSDN博客文章浏览阅读897次&#xff0c;点赞23次&#xff0c;收藏13次。【教学类-64-04】20240619彩棒鱼骨图&#xff08;一&#xff09;6.5*1CM 6根棒子720种https:…

JetBrains Rider 2024安装教程

一、下载Rider 1、进入官网&#xff0c;点击“下载” 2、下载完毕 二、安装Rider 1、双击下载的exe文件 2、点击“下一步” 3、可以点击“浏览”选择安装路径&#xff0c;之后点击“下一步” 4、选中图中四项&#xff0c;点击“下一步” 5、选中图中四项&#xff0c;点击“下…

Go语言学习:每日一练1

Go语言学习&#xff1a;每日一练1 目录 Go语言学习&#xff1a;每日一练1变量声明函数定义流程控制 ifrange遍历switch 变量声明 package main//定义变量 var a 1 const Message “hello,world”func main() {b : 2 //短变量声明var c 3c TestMethod(a, b, c)} //定义函数…

进程、CPU、MMU与PCB之间的关系

目录 进程与cpu&#xff08;中央处理器&#xff09; 源代码、程序、cpu与进程的关系 cpu超线程 CPU的简易架构与处理数据过程 进程与MMU&#xff08;内存管理单元&#xff09; mmu作用 cpu和mmu的关系 进程与PCB&#xff08;进程控制块&#xff09; PCB介绍与内部成员…

组合数学、圆排列、离散数学多重集合笔记

自用 如果能帮到您&#xff0c;那也值得高兴 知识点 离散数学经典题目 多重集合组合 补充容斥原理公式 隔板法题目 全排列题目&#xff1a;

解决pip 无法使用

pip is configured with locations that require TLS/SSL,the ssl module in Python is not available python缺少SSL模块&#xff0c;pip默认安装源为https://pypi.org/simple/&#xff0c;连接是需要SSL库&#xff0c;写配置文件修改为阿里安装源。 pip config --global se…

Loki部署及使用

简介 loki 是云原生的日志服务,本文讲解loki的部署,日志接入和查询日志的简单使用。 理论 Loki 分两部分,Loki 是日志引擎部分,Promtail 是收集日志端。 Loki 是主服务器,负责存储日志和处理查询 。 promtail 是代理,负责收集日志并将其发送给 loki 。 promtail 是日志…

武汉星起航:全球化舞台,中国跨境电商品牌力与竞争力双提升

随着全球化步伐的加快和数字技术的迅猛发展&#xff0c;跨境出口电商模式已经成为中国企业海外拓展的重要战略选择。这一模式不仅为中国的中小型企业提供了进军全球市场的机会&#xff0c;更为它们在全球舞台上展示独特的竞争优势提供了强有力的支撑。武汉星起航将从市场拓宽、…

学习时间的运用:

接下来的学习时间&#xff1a;14:19-17:50,以30min为一个基础时间&#xff0c;然后刷题&#xff0c;纠正自己的学习习惯和做题习惯还有自己的思维陷阱和自己的思维误区&#xff0c;使自己得到一个不断地成长和进步还有学习&#xff0c;这样对于自己而言&#xff0c;自己所可以得…

Kylin模型设计的最佳实践:提升大数据平台性能的策略

摘要 Apache Kylin是一个开源的分布式分析引擎&#xff0c;提供对大数据集的高性能查询能力。Kylin通过预计算技术&#xff0c;将数据以多维立方体&#xff08;Cube&#xff09;的形式存储&#xff0c;从而加快查询速度。模型设计在Kylin中至关重要&#xff0c;它直接影响到查…

江协科技51单片机学习- p19 串口通信

前言&#xff1a; 本文是根据哔哩哔哩网站上“江协科技51单片机”视频的学习笔记&#xff0c;在这里会记录下江协科技51单片机开发板的配套视频教程所作的实验和学习笔记内容。本文大量引用了江协科技51单片机教学视频和链接中的内容。 引用&#xff1a; 51单片机入门教程-2…

Java Stream API揭秘:掌握List流操作,打造高效数据处理流程

序言 Java Stream API是Java 8中引入的一个非常重要的功能组成部分&#xff0c;它提供了一种声明式的处理数据集合的方法。它主要特点是基于函数式编程的理念&#xff0c;允许我们以更加简洁、高效的方式进行集合的处理、转换和过滤。通过Stream API&#xff0c;我们可以灵活地…

【LangChain系列——案例分析】【基于SQL+CSV的案例分析】【持续更新中】

目录 前言一、LangChain介绍二、在SQL问答时如何更好的提示&#xff1f;2-1、安装2-2、SQLite 样例数据2-3、使用langchain与其进行交互2-4、查看模型提示语2-5、提供表定义和示例行2-6、将表信息插入到Prompt中去2-7、添加自然语言->SQL示例2-8、在向量数据库中查找最相关的…

JAVA开发的一套医院绩效考核系统源码:KPI关键绩效指标的清晰归纳

KPI是关键绩效指标&#xff08;Key Performance Indicators&#xff09;的缩写&#xff0c;它是一种用于衡量员工或组织绩效的量化指标。这些指标通常与组织的目标和战略相关&#xff0c;并帮助管理层评估员工和组织的实际表现。KPI还可以为员工提供清晰的方向&#xff0c;使他…

python读取mp4视频,读取摄像头代码

python读取mp4视频 import cv2# 读取视频文件 video_path path_to_your_video.mp4 # 将此处替换为你的MP4文件路径 cap cv2.VideoCapture(video_path)# 检查视频是否成功打开 if not cap.isOpened():print("Error: Could not open video.")exit()# 播放视频 whil…

ASP.NET Core 6.0 使用 资源过滤器和行为过滤器

1.AOP 面向切面编程 概念 AOP(Aspect-Oriented Programming,面向切面编程)是一种编程范式,旨在通过预定义的模式(即“切面”)对程序的横切关注点进行模块化。横切关注点是一个在多个应用模块中出现的概念,例如日志记录、事务管理、安全检查等。AOP允许开发者定义“切面”…