当前位置:

首页 > 编程开发 > Python多进程怎么用?multiprocessing模块全解析

Python多进程怎么用?multiprocessing模块全解析

Python中绕过GIL实现真正并行计算的最直接方式是使用multiprocessing模块;2.该模块通过创建独立进程,每个进程拥有自己的解释器和内存空间,从而实现多核CPU并行计算;3.multiprocessing提供了Process类创建和管理进程、Queue/Pipe实现进程间通信、以及Pool用于高效管理大量任务;4.多进程适用于CPU密集型任务,而多线程受限于GIL更适合I/O密集型任务;5.进程间通信可通过队列(Queue)、管道(Pipe)和共享内存(SharedMemory)实现,各自

本文目录

    Python中绕过GIL实现真正并行计算的最直接方式是使用multiprocessing模块;2. 该模块通过创建独立进程,每个进程拥有自己的解释器和内存空间,从而实现多核CPU并行计算;3. multiprocessing提供了Process类创建和管理进程、Queue/Pipe实现进程间通信、以及Pool用于高效管理大量任务;4. 多进程适用于CPU密集型任务,而多线程受限于GIL更适合I/O密集型任务;5. 进程间通信可通过队列(Queue)、管道(Pipe)和共享内存(Shared Memory)实现,各自适用于不同场景;6. 使用Pool能有效管理大量并发任务,简化资源调度与结果收集,提升代码可维护性和执行效率。

    Python中如何使用多进程?multiprocessing模块详解

    Python中要实现真正的并行计算,绕过全局解释器锁(GIL)的限制,最直接有效的方式就是使用multiprocessing模块。它允许我们创建独立的进程,每个进程都有自己的Python解释器和内存空间,从而能够充分利用多核CPU的计算能力。

    Python中如何使用多进程?multiprocessing模块详解

    解决方案

    使用multiprocessing模块的核心是Process类。你可以创建一个Process对象,指定它要执行的目标函数,然后启动它。

    import multiprocessing
    import os
    import time
    
    def worker_function(name, delay):
        """一个简单的模拟工作函数"""
        pid = os.getpid()
        print(f"进程 {pid} ({name}) 开始工作...")
        time.sleep(delay) # 模拟耗时操作
        print(f"进程 {pid} ({name}) 完成工作。")
    
    if __name__ == '__main__':
        print("主进程开始。")
    
        # 创建两个进程
        process1 = multiprocessing.Process(target=worker_function, args=("任务A", 2))
        process2 = multiprocessing.Process(target=worker_function, args=("任务B", 1))
    
        # 启动进程
        process1.start()
        process2.start()
    
        # 等待所有子进程完成
        # join() 方法会阻塞主进程,直到对应的子进程执行完毕
        process1.join()
        process2.join()
    
        print("所有子进程已完成,主进程结束。")

    在这个例子里,worker_function会在独立的进程中运行。process1.start()和process2.start()会立即返回,而不会等待函数执行完毕,这就是并行执行的体现。join()方法则确保主进程在所有子进程结束之前不会退出。值得注意的是,if __name__ == '__main__':这行代码是必须的,尤其是在Windows系统上,它能确保子进程在启动时不会重复导入模块,避免无限循环创建进程的问题。

    Python中如何使用多进程?multiprocessing模块详解

    为什么需要多进程,它和多线程有什么区别?

    这个问题,我个人觉得,是理解Python并发编程的关键。很多人刚开始接触时会混淆多线程和多进程,甚至觉得多线程就足够了。但实际上,对于CPU密集型任务,Python的多线程因为全局解释器锁(GIL)的存在,并不能实现真正的并行计算。GIL一次只允许一个线程执行Python字节码,这意味着即便你有多个线程,它们也只能轮流执行,无法同时利用多核CPU。

    而多进程则完全不同。每个进程都有自己独立的内存空间和Python解释器实例,它们之间是相互隔离的。这意味着,一个进程的执行不会受到另一个进程中GIL的限制。所以,当你的任务是计算密集型(比如大量数学运算、数据处理等),需要榨干CPU的性能时,多进程就是你的不二之选。

    Python中如何使用多进程?multiprocessing模块详解

    简单来说:

    • 多线程: 线程共享同一进程的内存空间。适用于I/O密集型任务(如网络请求、文件读写),因为在等待I/O时,GIL会被释放,其他线程可以继续执行。但对于CPU密集型任务,受限于GIL,无法真正并行。
    • 多进程: 进程拥有独立的内存空间。适用于CPU密集型任务,可以充分利用多核CPU实现真正的并行计算。进程间通信相对复杂一些,因为它们不共享内存。

    所以,选择多进程还是多线程,很大程度上取决于你的任务类型。

    如何在多进程间共享数据和通信?

    一开始接触多进程,最头疼的就是数据共享。你不能像多线程那样直接改个全局变量就完事儿,那样会出大问题。因为每个进程都有自己的内存副本,直接修改是无效的。得换个思路,比如把数据“扔”进队列里,让另一个进程去“捞”出来,这才是正道。multiprocessing模块提供了几种机制来处理进程间通信(IPC):

    1. 队列(Queue): 这是最常用、最灵活的方式,适用于任何类型的数据。Queue是进程安全的,可以用来在生产者-消费者模式中传递消息。

      import multiprocessing
      import time
      
      def producer(queue):
          for i in range(5):
              msg = f"消息 {i}"
              queue.put(msg)
              print(f"生产者发送: {msg}")
              time.sleep(0.5)
          queue.put(None) # 发送结束信号
      
      def consumer(queue):
          while True:
              msg = queue.get()
              if msg is None: # 收到结束信号
                  break
              print(f"消费者接收: {msg}")
              time.sleep(0.8)
      
      if __name__ == '__main__':
          q = multiprocessing.Queue()
          p1 = multiprocessing.Process(target=producer, args=(q,))
          p2 = multiprocessing.Process(target=consumer, args=(q,))
      
          p1.start()
          p2.start()
      
          p1.join()
          p2.join()
          print("队列通信示例结束。")
    2. 管道(Pipe): Pipe用于两个进程之间的双向或单向通信。它比Queue更轻量级,但只能用于两个进程。

      import multiprocessing
      
      def sender(conn):
          conn.send("你好,我是发送方!")
          conn.close()
      
      def receiver(conn):
          msg = conn.recv()
          print(f"接收方收到: {msg}")
          conn.close()
      
      if __name__ == '__main__':
          parent_conn, child_conn = multiprocessing.Pipe() # 创建管道
          p1 = multiprocessing.Process(target=sender, args=(child_conn,))
          p2 = multiprocessing.Process(target=receiver, args=(parent_conn,))
      
          p1.start()
          p2.start()
      
          p1.join()
          p2.join()
          print("管道通信示例结束。")
    3. 共享内存(Shared Memory): 对于简单的数值类型或数组,可以使用Value和Array来在进程间共享。但需要注意的是,它们本身不提供同步机制,你可能还需要Lock来避免竞态条件。

      import multiprocessing
      
      def increment(num, arr, lock):
          lock.acquire() # 获取锁
          try:
              num.value += 1
              for i in range(len(arr)):
                  arr[i] += 1
              print(f"进程 {multiprocessing.current_process().name} 修改后: num={num.value}, arr={list(arr)}")
          finally:
              lock.release() # 释放锁
      
      if __name__ == '__main__':
          num = multiprocessing.Value('i', 0) # 共享整数
          arr = multiprocessing.Array('i', [0, 0, 0]) # 共享整数数组
          lock = multiprocessing.Lock() # 共享锁
      
          processes = []
          for i in range(3):
              p = multiprocessing.Process(target=increment, args=(num, arr, lock), name=f"Worker-{i}")
              processes.append(p)
              p.start()
      
          for p in processes:
              p.join()
      
          print(f"最终结果: num={num.value}, arr={list(arr)}")

    选择哪种方式取决于你的具体需求:Queue是最通用的,Pipe适用于点对点通信,而共享内存则适用于需要直接访问共享数据且对性能有较高要求的场景,但需要手动处理同步。

    使用进程池(Pool)管理大量任务的优势是什么?

    说实话,一开始我总想着自己手动Process().start()、join(),但任务一多起来,比如要处理成百上千个文件,或者对大量数据进行并行计算,那代码就没法看了,而且手动管理进程的生命周期、资源限制也变得非常麻烦。Pool这东西,简直是“解放双手”的神器,它把那些烦人的进程生命周期管理、任务调度都给封装好了,我们只需要关注任务本身就行。

    Pool类提供了一种更高级的方式来管理一组工作进程,它可以自动分配任务给这些进程,并在任务完成后回收资源。

    主要优势:

    • 资源管理: 可以限制同时运行的进程数量,避免创建过多进程耗尽系统资源。
    • 任务分发: 提供了方便的方法(如map、apply)将任务分发给进程池中的工作进程。
    • 结果收集: 能够方便地收集各个任务的执行结果。

    最常用的方法是map()和apply_async():

    1. pool.map(func, iterable): 类似于内置的map()函数,它将iterable中的每个元素作为参数传递给func,并并行执行。它会阻塞直到所有结果都返回。

      import multiprocessing
      import time
      
      def square(x):
          time.sleep(0.1) # 模拟计算
          return x * x
      
      if __name__ == '__main__':
          with multiprocessing.Pool(processes=4) as pool: # 创建一个包含4个工作进程的进程池
              # 使用map并行计算列表元素的平方
              results = pool.map(square, range(10))
              print(f"使用map计算结果: {results}")
    2. pool.apply_async(func, args=(), kwds={}): 提交一个任务到进程池,并立即返回一个AsyncResult对象。你可以通过AsyncResult.get()方法获取结果(会阻塞直到结果可用),或者通过AsyncResult.ready()、AsyncResult.successful()检查任务状态。这适用于需要异步处理结果,或者任务参数不适合map的情况。

      import multiprocessing
      import time
      
      def complex_task(a, b):
          time.sleep(0.5)
          return f"计算 {a} + {b} = {a + b}"
      
      if __name__ == '__main__':
          with multiprocessing.Pool(processes=3) as pool:
              # 提交异步任务
              async_result1 = pool.apply_async(complex_task, args=(1, 2))
              async_result2 = pool.apply_async(complex_task, args=(3, 4))
              async_result3 = pool.apply_async(complex_task, args=(5, 6))
      
              # 可以做其他事情,然后获取结果
              print("主进程在等待结果...")
              result1 = async_result1.get()
              result2 = async_result2.get()
              result3 = async_result3.get()
      
              print(f"结果1: {result1}")
              print(f"结果2: {result2}")
              print(f"结果3: {result3}")

    使用with语句管理Pool是非常推荐的,它能确保进程池在代码块执行完毕后被正确关闭,释放所有资源。Pool是处理大量独立任务的理想选择,它极大地简化了并行编程的复杂性。

    本站声明:本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系bd@zhengruan.com
    作者最新文章
    编程开发
    相关文章 更多
    GitHub六个AI开源项目能做什么?软件理解、语音与求职场景
    GitHub六个AI开源项目能做什么?软件理解、语音与求职场景

    解析六个GitHub AI开源项目的具体用途,包括软件静态分析、智能体回答检查、多语言配音、求职材料生成、本地代码检索及动态歌词展示,帮助开发者根据实际需求筛选工具并正确验证结果。

    opencode安装skills教程及本地配置方法
    opencode安装skills教程及本地配置方法

    遇到OpenCode Skills无法加载或配置无效?本文手把手教你完成Skills的安装、环境变量设置及本地调试,避开常见坑点,让AI助手更懂你的代码习惯。

    如何开启Visual Studio2022实时代码分析警告提示
    如何开启Visual Studio2022实时代码分析警告提示

    解决 Visual Studio 2022 编辑时不显示代码分析警告的问题。指南涵盖 .NET 项目实时分析设置、Roslyn 分析器范围调整及错误列表来源筛选,确保开发者能高效利用实时代码诊断功能。

    如何在Visual Studio2022查看变量监视窗口调试程序
    如何在Visual Studio2022查看变量监视窗口调试程序

    详解 Visual Studio 2022 调试技巧:包括断点设置、监视窗口开启方法、变量添加步骤以及通过 F10 单步执行观察变量值变化的全过程。

    Visual Studio2017设置默认编码为UTF-8不带BOM
    Visual Studio2017设置默认编码为UTF-8不带BOM

    针对 Visual Studio 2017 缺乏全局默认编码选项的情况,详解如何利用 .editorconfig 设定项目级 UTF-8 无 BOM 规则,以及手动转换现有文件并校验字节的方法。

    Visual Studio2022F5调试提示启动项目未配置怎么修复
    Visual Studio2022F5调试提示启动项目未配置怎么修复

    解决 Visual Studio 2022 F5 调试报错问题,通过设置启动项目、检查解决方案属性及正确区分类库与应用项目,快速恢复调试功能。

    Visual Studio2022NuGet包还原失败离线处理方案
    Visual Studio2022NuGet包还原失败离线处理方案

    解决Visual Studio 2022离线环境中NuGet包还原失败的难题,涵盖依赖链分析、本地源配置、包集收集及隔离验证步骤,帮助开发者构建稳定的离线开发环境。

    Visual Studio2017大项目加载缓慢,优化加载性能技巧
    Visual Studio2017大项目加载缓慢,优化加载性能技巧

    解决Visual Studio 2017大型项目加载慢的实用指南。涵盖性能监测、扩展管理、文档恢复优化及版本兼容性检查,帮助开发者精准定位瓶颈并提升工作效率。

    Visual Studio2022设置多启动项目同时调试运行
    Visual Studio2022设置多启动项目同时调试运行

    详解 Visual Studio 2022 多启动项目配置方法,包括启动动作选择、顺序调整及调试技巧,帮助开发者高效调试分布式或前后端分离应用。

    fastapi下载文件接口实现教程
    fastapi下载文件接口实现教程

    深入解析在FastAPI框架中实现文件下载接口的完整方案,涵盖基于FileResponse的本地静态文件传输、基于StreamingResponse的分块流式传输、RFC 5987中文文件名编码规范、路径穿越安全防御及BackgroundTasks临时文件清理,并配备详细代码示例与架构解析图。

    查看更多
    精品专题 更多
    装机必备
    装机必备

    正软商城装机必备专区,精选办公、浏览器、安全防护、影音播放、压缩解压、设计创作和系统工具等电脑常用正版软件,帮助用户快速完成新电脑软件配置。

    Windows
    Windows

    正软商城Windows软件专区,汇集适用于Windows电脑的办公、设计、安全防护、影音播放、开发工具和系统优化软件,提供软件介绍、系统要求、正版授权及购买下载服务。

    PDF教程
    PDF教程

    正软商城PDF教程频道提供PDF编辑、转换、合并、拆分、压缩及格式处理方法,同时介绍常用PDF软件和工具的使用技巧。

    Mac软件 更多
    讯飞智作 网页版
    讯飞智作 网页版
    Windows/ macOS/ Linux

    讯飞智作是一款基于语音合成技术、虚拟人驱动技术与数字人形象声音构建能力的 AI 数字人音视频创作平台。

    火山引擎 网页版
    火山引擎 网页版
    Windows/ macOS/ Linux

    火山引擎是字节跳动旗下企业级云与AI服务平台。聚焦大模型核心能力,依托字节自研豆包多模态大模型,凭借火山方舟一站式平台,提供模型精调、推理部署、智能应用搭建等全链路服务,结合高性能AI算力,助力各行业快速落地大模型数字化与智能化应用。

    Aperty macOS版
    Aperty macOS版
    macOS

    Aperty 是 Skylum 推出的 AI 人像修图软件,支持自然肤质修饰、瑕疵处理、面部与身体调整、预设及批量同步。

    WINDOWS 更多
    讯飞智作 网页版
    讯飞智作 网页版
    Windows/ macOS/ Linux

    讯飞智作是一款基于语音合成技术、虚拟人驱动技术与数字人形象声音构建能力的 AI 数字人音视频创作平台。

    火山引擎 网页版
    火山引擎 网页版
    Windows/ macOS/ Linux

    火山引擎是字节跳动旗下企业级云与AI服务平台。聚焦大模型核心能力,依托字节自研豆包多模态大模型,凭借火山方舟一站式平台,提供模型精调、推理部署、智能应用搭建等全链路服务,结合高性能AI算力,助力各行业快速落地大模型数字化与智能化应用。

    PixTV 网页版
    PixTV 网页版
    Windows

    PixTV 是一款在浏览器中使用的 AI 视觉内容创作平台,提供图片、视频、音频、文字生成、AI 分镜、局部重绘、提示词反推和无限画布等工具,适合短剧、漫剧、广告及社交媒体内容制作。