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

Python中如何使用多进程?multiprocessing模块详解
最新回答
魔怪小姐

2020-06-27 13:09:25

Python中通过multiprocessing模块实现多进程的核心方式是利用Process类创建进程,结合队列、管道或共享内存进行通信,并通过Pool管理大量任务。 以下是详细说明:

1. 基础进程创建与启动

使用multiprocessing.Process类创建独立进程,每个进程拥有独立的Python解释器和内存空间,可绕过GIL实现并行计算。

  • 核心步骤

    定义目标函数(进程要执行的逻辑)。

    创建Process对象,指定target(目标函数)和args(参数)。

    调用start()启动进程,join()等待进程结束。

import multiprocessingimport osimport timedef worker_function(name, delay): pid = os.getpid() print(f"进程 {pid} ({name}) 开始工作...") time.sleep(delay) print(f"进程 {pid} ({name}) 完成工作。")if __name__ == '__main__': process1 = multiprocessing.Process(target=worker_function, args=("任务A", 2)) process2 = multiprocessing.Process(target=worker_function, args=("任务B", 1)) process1.start() process2.start() process1.join() process2.join() print("所有子进程已完成,主进程结束。")
  • 关键点

    if __name__ == '__main__'::在Windows系统中必须使用,避免子进程重复导入模块导致无限递归。

    并行性:start()后主进程继续执行,子进程在后台运行,实现并行。

2. 多进程 vs 多线程
  • 多线程

    共享同一进程的内存空间,适合I/O密集型任务(如网络源慎请求、文件读写)。

    受GIL限制,无法真正并行执行CPU密集型任务。

  • 多进程

    每个进程有独立内存空间,适合CPU密集型任务(如数学运算雹念敬、数据处理)。

    无GIL限制,可充分利用多核CPU。

3. 进程间通信(IPC)

进程间不共享内存,需通过以下机制通信:

(1)队列(Queue)
  • 特点:线程/进程安全,支持生产者-消费者模式。
  • 示例
import multiprocessingdef producer(queue): for i in range(5): queue.put(f"消息 {i}") queue.put(None) # 结束信号def consumer(queue): while True: msg = queue.get() if msg is None: break print(f"消费者接收: {msg}")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()(2)管道(Pipe)
  • 特点:轻量级,仅适用于两个进程间的双向或单向通信。
  • 示例
import multiprocessingdef 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()(3)共享内存(Shared Memory)
  • 特点:直接共享数值或数组,需手动同步(如使用Lock)。
  • 示例
import multiprocessingdef increment(num, arr, lock): lock.acquire() try: num.value += 1 for i in range(len(arr)): arr[i] += 1 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)}")4. 进程池(Pool)管理大量任务

Pool类自动管理进程生命周期,简化任务分发和结果收集,适合处理大量独立任务。

核心优势
  • 资源控制:限制最大进程数(如processes=4)。
  • 任务分发:通过map或apply_async分配任务。
  • 结果收集:自动汇总结果,避免手动同步。
常用方法
  • pool.map(func, iterable)

    阻塞式并行执行,类似内置map。

    import multiprocessingdef square(x): return x * xif __name__ == '__main__': with multiprocessing.Pool(processes=4) as pool: results = pool.map(square, range(10)) print(f"结果: {results}")
  • pool.apply_async(func, args)

    非阻塞式提交任务,返回AsyncResult对象。

    import multiprocessingdef complex_task(a, b): 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)) print(async_result1.get()) # 阻塞获取结果 print(async_result2.get())
总结
  • 适用场景

    多进程:CPU密集型任务(如科学计算、图像处理)。

    多线程:I/O密集型任务(如网络爬虫、文件操作)。

  • 关键模块

    Process:基础进程创建。

    Queue/Pipe/Shared Memory:进程间通信。

    Pool:高效管理大量任务。

通过合理选择通信机制和任务管理方式,可显著提升Python程序的并行性能。