深入理解Python多进程

目录

一、引言

二、Python多进程基础

进程与线程的区别

Python多进程模块

三、Python多进程实现原理

进程创建

进程间通信

进程同步

四、Python多进程使用方法

创建进程

进程间通信

五、实战案例

六、总结    


一、引言

在Python编程中,多进程是一种重要的并发编程技术,它允许程序同时执行多个任务,从而显著提高程序的执行效率。特别是在处理I/O密集型任务或计算密集型任务时,多进程能够充分利用多核CPU资源,实现真正的并行计算。本文将从基础概念出发,逐步深入Python多进程的实现原理、使用方法以及实战案例,帮助读者全面理解和掌握Python多进程编程。

二、Python多进程基础

进程与线程的区别

进程是系统分配资源的基本单位,它拥有独立的内存空间和系统资源;而线程是CPU调度的基本单位,多个线程共享同一进程的内存空间和系统资源。因此,进程之间通信需要通过IPC(进程间通信)机制,而线程之间通信则相对简单。

Python中的threading模块支持多线程编程,但由于全局解释器锁(GIL)的存在,Python多线程在CPU密集型任务上并不能实现真正的并行计算。而多进程则不受GIL的限制,能够实现真正的并行计算。

Python多进程模块

Python提供了multiprocessing模块来支持多进程编程。该模块提供了一个类似于threading模块的API,但它是基于进程的。multiprocessing模块支持创建进程、进程间通信、进程同步等功能。

三、Python多进程实现原理

进程创建

在Python中,可以使用multiprocessing.Process类来创建进程。每个进程都是一个独立的Python解释器实例,它们之间通过管道、队列等方式进行通信。创建进程时,需要指定一个目标函数(即子进程要执行的函数)以及传递给该函数的参数。

进程间通信

进程间通信(IPC)是多进程编程中的一个重要问题。Python提供了多种IPC机制,包括管道(Pipe)、队列(Queue)、共享内存(SharedMemory)等。其中,队列是最常用的一种IPC机制,它提供了一个先进先出的数据结构,用于在进程之间传递数据。

进程同步

进程同步是多进程编程中的另一个重要问题。由于多个进程可能同时访问共享资源(如文件、数据库等),因此需要采取一些同步措施来避免竞态条件和数据不一致等问题。Python提供了多种同步原语,包括锁(Lock)、条件变量(Condition)、信号量(Semaphore)等。

四、Python多进程使用方法

创建进程

使用multiprocessing.Process类创建进程的基本语法如下:

from multiprocessing import Process  
  
def worker(num):  
    print(f'Worker {num} is running')  
  
if __name__ == '__main__':  
    p1 = Process(target=worker, args=(1,))  
    p2 = Process(target=worker, args=(2,))  
    p1.start()  
    p2.start()  
    p1.join()  
    p2.join()

在上面的示例中,我们定义了一个名为worker的函数作为子进程的目标函数。然后,我们创建了两个Process对象p1和p2,并将worker函数作为它们的目标函数。接着,我们调用start()方法启动这两个进程,并使用join()方法等待它们执行完毕。

进程间通信

使用队列进行进程间通信的示例如下:

from multiprocessing import Process, Queue  
  
def worker(q):  
    q.put('Hello from worker')  
  
if __name__ == '__main__':  
    q = Queue()  
    p = Process(target=worker, args=(q,))  
    p.start()  
    print(q.get())  # 输出:Hello from worker  
    p.join()

在上面的示例中,我们创建了一个Queue对象q作为进程间通信的通道。然后,我们创建了一个子进程p,并将q作为参数传递给它的目标函数worker。在worker函数中,我们使用put()方法向队列中发送一条消息。在主进程中,我们使用get()方法从队列中接收并打印这条消息。

五、实战案例

下面是一个使用Python多进程进行网络爬虫的实战案例。假设我们需要从多个网站上爬取数据,并保存到本地文件中。由于每个网站的爬取过程都是独立的,因此可以使用多进程来实现并行爬取。

from multiprocessing import Pool  
import requests  
  
def fetch_data(url):  
    response = requests.get(url)  
    # 这里只是简单地将响应内容保存到文件中,实际情况下可能需要进行更复杂的处理  
    with open(f'{url.split("/")[-1]}.html', 'w') as f:  
        f.write(response.text)

if name == 'main':
        urls = [
                'http://example.com/page1',
                'http://example.com/page2',
                'http://example.com/page3',
                # ... 其他网址
        ]

        # 创建一个进程池,这里使用CPU核心数作为进程数  
        with Pool(processes=os.cpu_count()) as pool:  
                    # 使用map方法将urls列表中的每个元素作为参数传递给fetch_data函数  
                    # 并行执行这些函数  
                    pool.map(fetch_data, urls)  
 
                 print("所有网页数据已爬取并保存。")

在上面的实战案例中,我们使用了`multiprocessing.Pool`类来创建一个进程池。进程池允许我们并行地执行多个任务,而不需要手动创建和管理每个进程。我们使用`os.cpu_count()`函数来获取系统的CPU核心数,并将其作为进程池的大小。然后,我们使用`pool.map()`方法将`urls`列表中的每个URL作为参数传递给`fetch_data`函数,并并行地执行这些函数。最后,当所有函数执行完毕后,我们打印出一条消息表示所有网页数据已爬取并保存。    

六、总结    

本文深入介绍了Python多进程编程的基础概念、实现原理、使用方法以及实战案例。通过本文的学习,读者可以全面理解和掌握Python多进程编程的相关知识,并能够在实际项目中应用多进程技术来提高程序的执行效率。需要注意的是,虽然多进程技术能够带来性能上的提升,但也会带来一些额外的问题和复杂性,如进程间通信、进程同步等。因此,在使用多进程技术时,需要根据实际情况进行权衡和选择。

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

PartnerShare VS Tolt:出海SaaS选择哪种推广分销系统合适?

SaaS产品的成功在很大程度上取决于其推广策略的有效性。PartnerShare联盟系统和Tolt都是市场上比较知名的推广分销解决方案,能够帮助企业扩大用户基础并提高品牌知名度。 但是两款工具在某些特定任务上肯定有自己的独特优势,“找到你的锤子,…

SpringBoot-集成TOTP

TOTP验证码提供了一种高效且安全的身份验证方法。它不仅减少了依赖短信或其他通信方式带来的成本和延时,还通过不断变换的密码增加了破解的难度。未来,随着技术的进步和对安全性要求的提高,TOTP及其衍生技术将继续发展并被更广泛地应用。TOTP…

QT安装及项目创建

一、QT安装 1、安装qt_creater 方法一: 镜像文件:在2024-6-12:版本已经更新到了6.7 下载地址:https://download.qt.io/archive/qt/ 方法二: 百度网盘:链接:https://pan.baidu.com/s/1D0EmH…

SpringSecurity入门(一)

1、引入依赖 spring-boot版本2.7.3&#xff0c;如未特殊说明版本默认使用此版本 <dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-security</artifactId></dependency><dependency><g…

【Linux】基础IO [万字之作]

目录 一.重谈文件 二.重谈C文件操作 1.操作 1.文件的打开和关闭 2.文件的读写操作 ​编辑 1.fgetc函数 2.fputc函数 3.fputs函数 4.fgets函数 5.fprintf函数 6.fscanf函数 7.fread函数 8.fwrite函数 三.重谈当前路径 四.系统文件操作接口 1.Open函数 2.write函数 3…

hot100 -- 栈

目录 &#x1f6a9;有效的括号 &#x1f33c;最小栈 AC 栈 AC 链表 &#x1f33c;字符串解码 &#x1f43b;每日温度 &#x1f352;柱状图中的最大矩形 解释 AC 单调栈 &#x1f6a9;有效的括号 20. 有效的括号 - 力扣&#xff08;LeetCode&#xff09; 1&#xf…

[初阶数据结构] 包装类 | 泛型

目录 一. 包装类 1.1 什么是包装类? 1.2 包装类的意义 1.3 基本数据类型与包装类 1.4 装箱 1.5 拆箱 1.6 小总结 二. 泛型 2.1 什么是泛型? 2.2 泛型的意义 2.3 泛型的语法 2.4 泛型的编译 2.4.1 下载插件 2.4.2 分析 2.5 上界 2.6 泛型方法 2.7 小总结 三. 总结 一.…

conda虚拟环境,安装pytorch cuda cudnn版本一致,最简单方式

1、pytorch版本安装&#xff08;卸载也会有问题&#xff09; &#xff08;1&#xff09;版本如何选择参考和卸载 https://zhuanlan.zhihu.com/p/401931724 &#xff08;2&#xff09;对应版本如何安装命令 https://pytorch.org/get-started/previous-versions/ 最简答安装参考…

递推算法及相关问题详解

目录 递推的概念 训练&#xff1a;斐波那契数列 解析 参考代码 训练&#xff1a;上台阶 参考代码 训练&#xff1a;信封 解析 参考代码 递推的概念 递推是一种处理问题的重要方法。 递推通过对问题的分析&#xff0c;找到问题相邻项之间的关系&#xff08;递推式&a…

实验滤膜等分切割器八等分90mm

名称:滤膜切分器 型号: RNKF-90 适用范围:切分φ90mm玻璃纤维滤膜、石英纤维滤膜 等分数:2等分、4等分、8等分 使用方法: 1、开盖:逆时针旋转防尘盖&#xff0c;与切分台分开后&#xff0c;轻放于台面。 2、放膜:持专用镊子,镊子的长尖在下,短尖在上,取待切分滤膜1片,采样…

配置响应拦截器,全局前置导航守卫

1&#xff1a;配置响应拦截器 响应拦截器&#xff0c;统一处理接口的错误 问题&#xff1a;每次请求&#xff0c;都会有可能会错误&#xff0c;就都需要错误提示 说明&#xff1a;响应拦截器是咱们拿到数据的 第一个 数据流转站&#xff0c;可以在里面统一处理错误。 // 添…

uniapp小程序计算地图计算距离

我们拿到自身和目标距离经纬度 调用此方法即可计算出自身与目标的距离 最后我所展示的页面如下 具体效果可能会有点偏差 要求严格的可以在精细的计算一下

ant组件库日期选择器汉化

ant组件库日期选择器默认英文 如何汉化 跟着官网走不能完全实现汉化。 这里提供一个解决方案&#xff0c;首先&#xff0c;通过pnpm下载moment包。 然后引入和注册文件&#xff1a; import zhCN from ant-design-vue/es/locale/zh_CN;import moment from moment;moment.loca…

vue30:v-model语法糖的本质

在Vue.js框架中&#xff0c;v-model 是一个指令&#xff0c;用于在表单输入和应用状态之间创建双向数据绑定。它本质上是语法糖&#xff0c;意味着它提供了一种更简洁的方式来编写代码&#xff0c;而不需要显式地编写额外的代码。 具体来说&#xff0c;v-model 背后实际上是由…

外汇天眼:Equals集团发布战略评估通知:MDP不再考虑收购提议

Equals Group plc (LON)今天发布了一份关于其战略评估的通知。 Equals公司不再与Madison Dearborn Partners, LLC (MDP)就公司的收购提议进行讨论。MDP因此发布了一份声明&#xff0c;确认其不打算为公司提出收购提议。 然而&#xff0c;MDP与其投资组合公司MoneyGram Interna…

台式电脑怎么连WiFi?4个宝藏方法收藏好!

“我有一部台式电脑&#xff0c;现在不知道应该怎么操作才能让电脑正确连接WiFi&#xff0c;不知道大家有什么简单的连接方法吗&#xff1f;希望可以给我出出主意。” 随着无线网络的普及和科技的飞速发展&#xff0c;越来越多人选择使用WiFi来连接互联网。对于笔记本电脑和移动…

计算机网络(3) 字节顺序:网络字节序与IPv4

一.小端与大端 小端&#xff08;Little endian&#xff09;&#xff1a;低字节保存在内存低地址&#xff0c;高字节保存在内存高地址。 大端&#xff08;Big endian&#xff09;&#xff1a;低字节保存在内存高地址&#xff0c;高字节保存在内存低地址。 例如&#xff08;14…

Android 中USB-HID协议实现

前言 所有通过USB连接android设备进行通讯的步骤都是大同小异&#xff1a;查询usb设备列表 ——>匹配对应的设备类型&#xff08;如productid , vendorId&#xff09;等——>连接usb设备&#xff0c;找到连接通讯的节点——>配置通讯信息&#xff0c;进行通讯。以上是…

Java数据结构之ArrayList(如果想知道Java中有关ArrayList的知识点,那么只看这一篇就足够了!)

前言&#xff1a;ArrayList是Java中最常用的动态数组实现之一&#xff0c;它提供了便捷的操作接口和灵活的扩展能力&#xff0c;使得在处理动态数据集合时非常方便。本文将深入探讨Java中ArrayList的实现原理、常用操作以及一些使用场景。 ✨✨✨这里是秋刀鱼不做梦的BLOG ✨✨…

鸿蒙开发:通过startAbilityByType拉起垂类应用

通过startAbilityByType拉起垂类应用 使用场景 开发者可通过特定的业务类型如导航、金融等&#xff0c;调用startAbilityByType接口拉起对应的垂域面板&#xff0c;该面板将展示目标方接入的垂域应用&#xff0c;由用户选择打开指定应用以实现相应的垂类意图。垂域面板为调用…