使用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,一经查实,立即删除!

相关文章

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

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

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

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

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

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

JetBrains Rider 2024安装教程

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

Go语言学习:每日一练1

Go语言学习:每日一练1 目录 Go语言学习:每日一练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(中央处理器) 源代码、程序、cpu与进程的关系 cpu超线程 CPU的简易架构与处理数据过程 进程与MMU(内存管理单元) mmu作用 cpu和mmu的关系 进程与PCB(进程控制块) PCB介绍与内部成员…

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

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

Loki部署及使用

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

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

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

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

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

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

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

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

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

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

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

办公软件汇总

1、OCR 1.1 pearOCR pearOCR 是一个免费的免费在线文字提取OCR工具网站。PearOCR界面简洁,所有过程均在网页端完成,无需下载任何软件,点开即用。官方地址:https://pearocr.com/ 参考:9款文字识别(OCR)工具…

Android性能分析工具-Perfetto基本使用

文章目录 一、Perfetto介绍二、抓取方法2.1 手机端直接抓取2.1.1 打开系统跟踪2.1.2 开始录制 2.2 使用 adb 抓取2.3 通过 Perfetto 网页自定义抓取 三、trace分析方法3.1 打开trace文件3.2 查看方法 一、Perfetto介绍 Perfetto 是一个用于性能检测和跟踪分析的生产级开源堆栈。…

Call_once

call_once和once_flag的声明 struct once_flag {constexpr once_flag() noexcept;once_flag(const once_flag&) delete;once_flag& operator(const once_flag&) delete; }; template<class Callable, class ...Args>void call_once(once_flag& flag, …

程序员如何用ChatGPT解决常见编程问题:实例解析

引言 在现代编程的世界中&#xff0c;技术进步日新月异&#xff0c;程序员们面临着各种各样的挑战和问题。解决这些问题的过程中&#xff0c;找到合适的工具至关重要。ChatGPT作为一种先进的人工智能语言模型&#xff0c;能够帮助程序员迅速、高效地解决常见的编程问题。本文将…

windows10/win11截图快捷键 和 剪贴板历史记录 快捷键

后知后觉的我今天又学了两招&#xff1a; windows10/win11截图快捷键 按 Windows 徽标键‌ Shift S。 选择屏幕截图的区域时&#xff0c;桌面将变暗。 默认情况下&#xff0c;选择“矩形模式”。 可以通过在工具栏中选择以下选项之一来更改截图的形状&#xff1a;“矩形模式”…

深度神经网络(dnn)--风格迁移(简单易懂)

概括 深度神经网络&#xff08;DNN&#xff09;在风格迁移领域的应用&#xff0c;实现了将一幅图像的艺术风格迁移到另一幅图像上的目标。该技术基于深度学习模型&#xff0c;特别是卷积神经网络&#xff08;CNN&#xff09;&#xff0c;通过提取内容图像的内容特征和风格图像的…

Python+Pytest+Yaml+Request+Allure+GitLab+Jenkins接口自动化测试框架概解

PythonPytestYamlAllure整体框架目录&#xff08;源代码请等下篇&#xff09; 框架详解 common:公共方法包 –get_path.py:获取文件路径方法 –logger_util.py:输出日志方法 –parameters_until.py&#xff1a;传参方式方法封装 –requests_util.py&#xff1a;请求方式方法封…