提升并行效率的Python多处理模块指南

news2024/9/28 19:24:24

在Python中,multiprocessing 模块提供了强大的多进程支持,能够帮助我们充分利用多核CPU资源来实现并行计算。相比传统的多线程模式,Python的多进程模式更加高效,因为它可以避免Python的全局解释器锁(GIL)对并发性能的限制。

为什么选择多进程?

Python的多线程模式受限于全局解释器锁(GIL),在处理CPU密集型任务时,多线程的并发效率会受到较大影响。而多进程模式通过为每个进程分配独立的内存空间,允许程序在多个CPU核上并行执行任务,能够显著提升CPU密集型任务的执行效率。

使用multiprocessing 模块,可以:

  • 创建独立的进程来执行任务,每个进程拥有独立的内存空间。

  • 在多个进程间共享数据或进行通信。

  • 通过进程池实现任务的并行执行。

  • 这里插播一条粉丝福利,如果你正在学习Python或者有计划学习Python,想要突破自我,对未来十分迷茫的,可以点击这里获取最新的Python学习资料和学习路线规划(免费分享,记得关注)

创建和启动进程

multiprocessing模块中,Process类用于创建和管理进程。每个进程都有自己的内存空间和全局变量,因此进程之间不会互相干扰。

创建一个简单的进程

import multiprocessing
import time

# 定义任务函数
def worker():
    print("任务开始执行")
    time.sleep(2)  # 模拟任务耗时
    print("任务结束")

if __name__ == "__main__":
    # 创建进程
    process = multiprocessing.Process(target=worker)
    
    # 启动进程
    process.start()
    
    # 等待进程执行完毕
    process.join()

在这个示例中,通过 multiprocessing.Process 创建了一个新的进程,并通过 start() 启动进程。join() 方法会阻塞主进程,直到子进程执行完毕。

多个进程并行执行

import multiprocessing
import time

def worker(number):
    print(f"任务{number}开始执行")
    time.sleep(2)
    print(f"任务{number}结束")

if __name__ == "__main__":
    # 创建多个进程
    processes = []
    for i in range(5):
        process = multiprocessing.Process(target=worker, args=(i,))
        processes.append(process)
        process.start()
    
    # 等待所有进程执行完毕
    for process in processes:
        process.join()

在这个示例中,启动了5个进程,每个进程并行执行各自的任务,主进程通过 join() 等待所有子进程完成。

进程间通信

在多进程编程中,进程间的通信是一个关键问题。由于每个进程都有自己独立的内存空间,无法像线程一样直接共享数据。multiprocessing模块提供了多种进程间通信的方式,包括QueuePipeManager等。

使用Queue进行进程间通信

Queue 是一种先进先出(FIFO)的数据结构,可以在多个进程之间安全地传递数据。

import multiprocessing

# 定义任务函数
def worker(q):
    q.put("任务完成")

if __name__ == "__main__":
    # 创建队列
    q = multiprocessing.Queue()

    # 创建进程并传入队列
    process = multiprocessing.Process(target=worker, args=(q,))
    process.start()
    process.join()

    # 从队列中获取数据
    result = q.get()
    print(result)

在这个示例中,子进程通过 q.put() 向队列中放入数据,主进程通过 q.get() 获取队列中的数据,实现了进程间的数据传递。

使用Pipe进行进程间通信

Pipe 是另一种进程间通信方式,它提供了一个双向的通信通道,适合在两个进程之间传递数据。

import multiprocessing

# 定义任务函数
def worker(conn):
    conn.send("来自子进程的消息")
    conn.close()

if __name__ == "__main__":
    # 创建管道
    parent_conn, child_conn = multiprocessing.Pipe()

    # 创建进程并传入管道的一端
    process = multiprocessing.Process(target=worker, args=(child_conn,))
    process.start()
    process.join()

    # 从管道另一端接收数据
    print(parent_conn.recv())

在这个示例中,使用 Pipe 实现了父子进程之间的双向通信。

进程池(Pool)

在某些场景中,需要并发执行大量的任务,而直接创建大量进程可能会导致系统资源耗尽。multiprocessing模块中的Pool类提供了一种管理多个进程的方式,通过进程池可以限制同时运行的进程数量,避免资源浪费。

使用Pool并发执行任务

import multiprocessing
import time

# 定义任务函数
def worker(number):
    print(f"任务{number}开始执行")
    time.sleep(2)
    print(f"任务{number}结束")

if __name__ == "__main__":
    # 创建进程池,最多允许3个进程同时运行
    with multiprocessing.Pool(3) as pool:
        pool.map(worker, range(5))

在这个示例中,Pool 创建了一个包含3个进程的进程池,map() 方法将任务分发给进程池中的进程并行执行。每个任务最多允许3个进程同时运行,其余任务会等待空闲进程。

异步任务执行

Pool.apply_async() 方法可以异步地提交任务,并通过回调函数处理结果。

import multiprocessing
import time

# 定义任务函数
def worker(number):
    time.sleep(2)
    return f"任务{number}完成"

# 定义回调函数
def callback(result):
    print(result)

if __name__ == "__main__":
    # 创建进程池
    with multiprocessing.Pool(3) as pool:
        for i in range(5):
            pool.apply_async(worker, args=(i,), callback=callback)

        # 等待所有任务完成
        pool.close()
        pool.join()

在这个示例中,apply_async() 提交任务后立即返回,主进程不会阻塞。任务执行完毕后,通过回调函数输出结果。

进程同步

由于多个进程在并发执行时,它们对共享资源的访问是无序的。因此,进程同步是保证数据一致性的重要手段。multiprocessing 模块提供了 LockSemaphore 等同步机制。

使用Lock保证进程同步

import multiprocessing
import time

# 定义任务函数
def worker(lock, number):
    with lock:  # 获取锁
        print(f"任务{number}开始")
        time.sleep(2)
        print(f"任务{number}结束")

if __name__ == "__main__":
    lock = multiprocessing.Lock()

    # 创建多个进程
    processes = []
    for i in range(5):
        process = multiprocessing.Process(target=worker, args=(lock, i))
        processes.append(process)
        process.start()

    # 等待所有进程完成
    for process in processes:
        process.join()

在这个示例中,Lock 用于确保同时只有一个进程可以执行受保护的代码块,防止进程之间的数据竞争。

共享内存

Python的multiprocessing模块还支持在进程间共享数据,ValueArray 类可以用于在进程间共享内存,避免复制数据。

使用ValueArray共享数据

import multiprocessing

# 定义任务函数
def worker(shared_value, shared_array):
    shared_value.value += 1
    for i in range(len(shared_array)):
        shared_array[i] += 1

if __name__ == "__main__":
    shared_value = multiprocessing.Value('i', 0)  # 共享整数
    shared_array = multiprocessing.Array('i', [1, 2, 3, 4, 5])  # 共享数组

    processes = []
    for _ in range(3):
        process = multiprocessing.Process(target=worker, args=(shared_value, shared_array))
        processes.append(process)
        process.start()

    for process in processes:
        process.join()

    print("共享值:", shared_value.value)
    print("共享数组:", shared_array[:])

在这个示例中,ValueArray 用于在多个进程间共享数据。每个进程都会对共享的数据进行修改,修改后的结果会反映在所有进程中。

总结

multiprocessing 模块是Python提供的多进程支持,旨在帮助开发者充分利用多核CPU资源,提升并发任务的执行效率。相比于受限于全局解释器锁(GIL)的多线程,multiprocessing 通过创建独立进程并分配各自的内存空间,避免了线程切换带来的性能瓶颈。本文详细介绍了如何使用 multiprocessing 创建和管理进程、进程间通信、进程池以及同步机制。通过掌握这些功能,开发者可以在处理CPU密集型任务时实现更高效的并行计算,提高程序的性能和扩展性。在需要执行大量并发任务的场景中,multiprocessing 是一个强大而灵活的工具。

最后,我精心筹备了一份全面的Python学习大礼包,完全免费分享给每一位渴望成长、希望突破自我现状却略感迷茫的朋友。无论您是编程新手还是希望深化技能的开发者,都欢迎加入我们的学习之旅,共同交流进步!

🌟 学习大礼包包含内容

Python全领域学习路线图:一目了然,指引您从基础到进阶,再到专业领域的每一步学习路径,明确各方向的核心知识点。

超百节Python精品视频课程:涵盖Python编程的必备基础知识、高效爬虫技术、以及深入的数据分析技能,让您技能全面升级。

实战案例集锦:精选超过100个实战项目案例,从理论到实践,让您在解决实际问题的过程中,深化理解,提升编程能力。

华为独家Python漫画教程:创新学习方式,以轻松幽默的漫画形式,让您随时随地,利用碎片时间也能高效学习Python。

互联网企业Python面试真题集:精选历年知名互联网企业面试真题,助您提前备战,面试准备更充分,职场晋升更顺利。

👉 立即领取方式:只需【点击这里】,即刻解锁您的Python学习新篇章!让我们携手并进,在编程的海洋里探索无限可能!

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

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

相关文章

一个超强大的Python数据探索工具

在数据分析的过程中,快速掌握数据集的基本特征是必不可少的一步。虽然 Pandas 提供了方便的 df.describe() 方法来生成数据摘要,但随着数据类型和分析需求的多样化,这一方法的局限性逐渐显现。Skimpy 作为一个新兴的 Python 包,旨…

基于mybatis-plus创建springboot,添加增删改查功能,使用postman来测试接口出现的常见错误

1 当你在使用postman检测 添加和更新功能时,报了一个500错误 查看idea发现是: Data truncation: Out of range value for column id at row 1 通过翻译:数据截断:表单第1行的“id”列出现范围外值。一般情况下,出现这个…

什么是Agent智能体?

你好,我是三桥君 近期,从各大厂商的年度大会到多个大型AI峰会,三桥君明显感受到行业风气的转变。这些会议不仅展示了众多AI Agent的实际应用案例,还有专家们对未来发展的预测。一时间,“Agent”这个词成为了热门词汇&…

Linux(含麒麟操作系统)如何实现多显示器屏幕采集录制

技术背景 在操作系统领域,很多核心技术掌握在国外企业手中。如果过度依赖国外技术,在国际形势变化、贸易摩擦等情况下,可能面临技术封锁和断供风险。开发国产操作系统可以降低这种风险,确保国家关键信息基础设施的稳定运行。在一…

多态的遗留问题以及C++中杂项,C++面试题

C面试题 1.什么是虚函数?什么是纯虚函数 虚函数:在类的继承中,基类中的函数前加virtual声明的函数就是虚函数。 虚函数实现了运行的多态,同一函数调用在不同对象中表现出不同的行为 纯虚函数:在基类中声明但没有实…

树莓派4B+UBUNTU20.04+静态ip+ssh配置

树莓派4B+UBUNTU20.04+静态ip+ssh配置 1.烧录Ubuntu镜像1.1选择pi 4b1.2选择ubuntu server (服务器版,无桌面)20.041.3选择sd卡1.4 点击右下角 NEXT ,编辑设置,输入密码,wifi选CN, 开启ssh1.5 烧录,依次点击“是”,等待完成2 烧录完成后装入树莓派,上电,等待系统完成配…

软件无线电3-微相E316和HackRF实现FM调制解调

前面介绍了基于Matlab、矢量信号器和HackRF One实现射频下的FM调制解调,今天分享的内容是用微相E316替代矢量信号器完成发射工作。注意本文仅用于科研和学习,私自搭建电台属于违法行为。 1.概述 微相E316和HackRF One实现FM调制解调测试框图如1所示&am…

离散化 ---( 求区间和)

什么是离散化? 离散化是将连续的数值范围映射到有限的、离散的数值集合的过程。在许多情况下,数据可能会存在多个重复值或范围较大的连续值。为了简化处理,尤其是处理区间查询和增量问题时,我们可以将这些值转换为一组有限的、唯一…

【重学 MySQL】四十、SQL 语句执行过程

【重学 MySQL】四十、SQL 语句执行过程 select 语句的完整结构select 语句执行顺序SQL 语句执行原理 select 语句的完整结构 SELECT 语句是 SQL(Structured Query Language)中用于从数据库表中检索数据的核心语句。一个完整的 SELECT 语句结构可以包括多…

Linux系统部署Mysql8.x修改密码并且设置远程连接

配置yum仓库配置yum仓库 # 更新密钥 rpm import https:repo.mysql.com/RPM-GPG-KEY- mysql-2023 # 安装Mysql8.x版本 yum库 rpm -Uvh https:dev.mysql.com/get/mysql80-community-release-el7-2.noarch.rpm 由于MySQL并不在CentOS的官方仓库中,所以我们通过上述rp…

跟李沐学AI:自注意力和位置编码

自注意力 自注意力机制(Self-Attention Mechanism),也被称为内部注意力(Intra-attention)或并行注意力(Parallel Attention),是一种在深度学习模型中用于处理序列数据的机制。它允许…

新版pycharm如何导入自定义环境

我们新的版本的pycharm的ui更改了,但是我不会导入新的环境了 我们先点击右上角的add interpreter 然后点击添加本地编译器 先导入这个bat文件 再点击load 我们就可以选择我们需要的环境了

解决毕业论文难题!推荐7款AI自动生成论文工具网站

在当今学术研究和写作领域,AI论文写作工具的出现极大地提高了写作效率和质量。这些工具不仅能够帮助研究人员快速生成论文草稿,还能进行内容优化、查重和排版等操作。以下是七款值得推荐的AI自动生成论文工具网站,特别推荐千笔-AIPassPaper。…

arthas简单应用

背景说明 项目上某个接口响应时间过长,需要查看方法耗时情况进行优化 安装配置 访问下载页进行下载:下载 | arthas 调整文件位置进行解压缩 - 查看arthas帮助命令(非必须,官网文档更详细) C:\tools\arthas\4.0.1\b…

移动技术开发:HandlerAsyncTask

1 实验名称 Handler&AsyncTask 2 实验目的 掌握使用Handler消息传递机制和AsyncTask处理后台线程周期性的改变Activity中界面控件的属性 3 实验源代码 布局文件代码&#xff1a; &#xff08;1&#xff09;HandlerTest <?xml version"1.0" encoding&quo…

《深度学习》—— ResNet 残差神经网络

文章目录 一、什么是ResNet&#xff1f;二、残差结构&#xff08;Residual Structure&#xff09;三、Batch Normalization&#xff08;BN----批归一化&#xff09; 一、什么是ResNet&#xff1f; ResNet 网络是在 2015年 由微软实验室中的何凯明等几位大神提出&#xff0c;斩获…

文新智能体开发:省钱有道,智慧选择,属于你的“省钱小诸葛”

开发灵感 在开发购物类智能体“省购小诸葛”时&#xff0c;我的灵感源自于对现代消费者购物行为的深刻洞察与未来科技趋势的展望。想象一个时代&#xff0c;当信息的海洋变得浩瀚无垠&#xff0c;消费者在众多商品与促销活动中遨游&#xff0c;却往往感到迷茫与疲惫。这时&…

在CANoe/CANalyzer中Replay Block“一键发送”一个诊断/命令序列

案例背景&#xff1a; 在博文《在CANoeCANalyzer中“在线回放”CAN Log.asc/blf文件_canoe怎么回放blf文件-CSDN博客https://blog.csdn.net/qfmzhu/article/details/128954931》我们介绍了Replay Block模块的一些典型应用。 下面我们介绍如何使用Replay Block代替IG(Interact…

OJ在线评测系统 后端 使用代理模式编写测试类 并 实现核心业务判题流程

编写测试类(代理模式) 实现示例的代码沙箱 package com.dduo.dduoj.judge.codesandbox.impl;import com.dduo.dduoj.judge.codesandbox.CodeSandbox; import com.dduo.dduoj.judge.codesandbox.model.ExecuteCodeRequest; import com.dduo.dduoj.judge.codesandbox.model.Exec…

Linux 冯诺依曼体系结构与操作系统概念

目录 0.前言 1. 冯诺依曼体系结构概述 1.1 输入单元 1.2 中央处理单元&#xff08;CPU&#xff09; 1.3 输出单元 2. 冯诺依曼体系结构的关键特性 2.1 所有数据流向内存 2.2 数据流动示例&#xff1a;QQ聊天过程 3. 操作系统 3.1 概念 3.2 设计操作系统的目的 3.3 操作系统的“…