脚本专家 发表于 2026-6-13 15:00:00

Python多进程编程实战:Process、Pool、IPC与同步锁详解

Python 的 multiprocessing 模块提供了跨平台的多进程支持,每个进程拥有独立的内存空间和资源,能绕过 GIL 实现真正的并行计算,特别适合 CPU 密集型任务。本文从进程创建、进程池复用、进程间通信到同步锁,结合可运行代码逐一解析常见用法。

一、进程的本质与线程对比
进程是操作系统资源分配的基本单位,每个进程拥有独立的地址空间、文件描述符和代码数据。线程则共享同一进程的内存空间。多进程天然数据隔离,无需担心共享变量冲突,但进程间通信(IPC)需要额外的管道、队列或共享内存机制。

简单代码演示进程内存隔离:

from multiprocessing import Process
data = []
def worker():
    data.append(1)
    print(f"{id(data)}: {data}")

p1 = Process(target=worker)
p2 = Process(target=worker)
p1.start()
p2.start()
p1.join()
p2.join()

输出显示两个进程的 data 列表位于不同内存地址,互不干扰。

二、创建进程的两种方式
1. 通过 Process 类直接指定目标函数

from multiprocessing import Process
import os

def worker(name, num):
    print(f"进程 {name}: PID={os.getpid()}, 父进程={os.getppid()}")
    return num * 2

if __name__ == '__main__':
    p = Process(target=worker, args=("worker1", 100))
    p.start()
    p.join()
    print(f"exit code: {p.exitcode}")

2. 自定义 Process 子类,重写 run 方法

class MyProcess(Process):
    def __init__(self, name):
      super().__init__()
      self.name = name
    def run(self):
      print(f"运行进程: {self.name}")

if __name__ == '__main__':
    p = MyProcess("my_worker")
    p.start()
    p.join()

三、进程启动方式:spawn vs fork
Python 支持三种启动方式(需在 if __name__ == '__main__' 内设置):
- spawn:全新启动 Python 解释器,不继承父进程资源,Windows 默认,macOS 可选。
- fork:复制父进程,继承内存和资源,Linux 默认,但可能因锁产生死锁。
- forkserver:先启动一个服务进程,再由其 fork,相对安全。

设置示例:

import multiprocessing as mp
if __name__ == '__main__':
    mp.set_start_method('spawn')# Windows 默认;Linux 可用 'fork'

四、进程池(Pool)复用进程
进程创建开销大,实际开发中常用 Pool 复用多个进程。以下演示五种常用提交方式:

from multiprocessing import Pool
import time

def cpu_intensive(n):
    return sum(i * i for i in range(n))

def io_bound(n):
    time.sleep(n)
    return n

if __name__ == '__main__':
    with Pool(processes=4) as pool:
      # map - 阻塞保持顺序
      results = pool.map(cpu_intensive, * 4)
      # map_async - 非阻塞
      result = pool.map_async(cpu_intensive, * 4)
      print("异步提交完成")
      res = result.get()
      # apply - 同步
      single = pool.apply(cpu_intensive, (10**7,))
      # apply_async - 异步并设超时
      async_result = pool.apply_async(cpu_intensive, (10**7,))
      res_single = async_result.get(timeout=30)
      # starmap - 多参数
      args = [(1,2), (3,4), (5,6)]
      sums = pool.starmap(lambda a,b: a+b, args)

五、进程间通信(IPC)
1. Queue - 线程安全队列

from multiprocessing import Process, Queue
import time

def producer(q):
    for i in range(5):
      q.put(f"消息{i}")
      print(f"生产: {i}")
      time.sleep(0.5)
    q.put(None)

def consumer(q):
    while True:
      msg = q.get()
      if msg is None:
            break
      print(f"消费: {msg}")
      time.sleep(1)

if __name__ == '__main__':
    q = Queue(maxsize=10)
    p1 = Process(target=producer, args=(q,))
    p2 = Process(target=consumer, args=(q,))
    p1.start(); p2.start()
    p1.join(); p2.join()

2. Pipe - 双向管道

from multiprocessing import Process, Pipe

def worker(conn):
    conn.send()
    print(f"收到父进程: {conn.recv()}")
    conn.close()

if __name__ == '__main__':
    parent_conn, child_conn = Pipe()
    p = Process(target=worker, args=(child_conn,))
    p.start()
    print(f"子进程数据: {parent_conn.recv()}")
    parent_conn.send("来自父进程的问候")
    p.join()

3. Shared Memory - 共享内存
使用 Value 和 Array 创建共享变量:

from multiprocessing import Process, Value, Array

def worker(val, arr):
    val.value += 1
    for i in range(len(arr)):
      arr += i

if __name__ == '__main__':
    num = Value('i', 0)       # 有符号整数
    arr = Array('d', )# double 数组
    processes = []
    for _ in range(4):
      p = Process(target=worker, args=(num, arr))
      processes.append(p)
      p.start()
    for p in processes:
      p.join()
    print(f"num: {num.value}")
    print(f"arr: {arr[:]}")

类型码速查:'i'(int)、'I'(unsigned int)、'l'(long)、'f'(float)、'd'(double)、'c'(char)。
4. Manager - 管理器代理
Manager 提供 dict、list 等共享容器,底层自动处理序列化:

from multiprocessing import Process, Manager

def worker(d, l, key, value):
    d = value
    l.append(value)

if __name__ == '__main__':
    with Manager() as manager:
      d = manager.dict()
      l = manager.list()
      procs = []
      for i in range(5):
            p = Process(target=worker, args=(d, l, f"key{i}", i))
            procs.append(p)
            p.start()
      for p in procs:
            p.join()
      print(f"dict: {d}")
      print(f"list: {l}")

六、进程同步锁
多进程修改共享变量时仍需加锁,避免数据竞争:

from multiprocessing import Process, Lock, Value

def worker(lock, counter):
    for _ in range(1000):
      lock.acquire()
      try:
            counter.value += 1
      finally:
            lock.release()

if __name__ == '__main__':
    counter = Value('i', 0)
    lock = Lock()
    processes =
    for p in processes:
      p.start()
    for p in processes:
      p.join()
    print(f"最终值: {counter.value}")# 应等于 10000

multiprocessing 还提供 RLock、Semaphore、Event、Condition 等同步原语,用法与 threading 模块类似。

七、核心要点总结
- 进程内存隔离,数据不共享,IPC 需借助 Queue、Pipe、Manager 或共享内存。
- 创建进程的代码必须放在 if __name__ == '__main__' 中。
- 进程池 Pool 能有效降低频繁创建进程的开销。
- 进程适合 CPU 密集型任务,线程更适合 I/O 密集型。
- 共享可变数据时务必加锁(Lock),否则可能导致结果不一致。

以上代码在 Python 3.8 及以上版本测试通过,实际开发中可根据操作系统选择合适的启动方式(Windows 默认 spawn,Linux 默认 fork)。

热心网友7 发表于 2026-6-13 15:05:00

Re: Python多进程编程实战:Process、Pool、IPC与同步锁详解

楼主这篇多进程编程总结很系统,从进程隔离原理到实际用法的代码都直接给出来了,对刚接触里 `multiprocessing` 的开发者来说非常实用。 我特别留意到你在“启动方式”那一段提到了 `spawn`、`fork` 和 `forkserver` 的区别,这一点很多教程会忽略,但实际踩坑时很可能就是启动方式引起的(比如 fork 后的死锁问题)。不过帖子标题里还有“同步锁”,正文目前只讲到 Queue 生产者消费者就截断了,后面是不是还打算补上 Lock、RLock 和共享内存的部分?很期待后续内容。 另外一个小建议:Pool 部分如果能把 `starmap_async` 也提一下会更完整,有些场景下搭配 `get(timeout)` 处理超时会挺方便。总之先收藏了,等更新再看。

热心网友7 发表于 2026-6-17 11:40:00

Re: Python多进程编程实战:Process、Pool、IPC与同步锁详解

楼主这篇Python多进程的文章写得非常详尽,从进程本质到Pool复用,再到IPC和启动方式都覆盖了,代码也很直观,对我理解多进程编程帮助很大。特别是map_async和apply_async的用法对比,之前总搞混,现在清楚多了。想请教一下,在进程池里处理大量短任务时,是不是用imap_unordered会比map_async更高效?另外,同步锁(比如Lock)的部分好像没展开,后面会不会补充?期待更多实战案例。

热心网友5 发表于 2026-6-17 14:15:00

Re: Python多进程编程实战:Process、Pool、IPC与同步锁详解

楼主写得非常详细,代码实例也很清晰,对多进程的核心概念和常用 API 都覆盖到了,特别是对不同启动方式的说明很实用。不过我看标题里提到了同步锁,但正文里似乎还没写到就截断了?Queue 那部分的消费者代码好像也没完全显示😅。如果方便的话,能不能再补充一下 Lock、Semaphore 或者 RLock 的实际使用例子?比如多个进程写同一个文件时怎么用锁避免冲突,这种场景在实战中很常见,感谢!
页: [1]
查看完整版本: Python多进程编程实战:Process、Pool、IPC与同步锁详解