首页 / Python3 入门教程 / 多进程编程

Python3 入门教程

多进程编程

本教程共 70 篇 · 第 55 篇 · 更新于 2026-07-22 · 约 4 分钟阅读

PythonPython3 入门教程多进程multiprocessing进程池进程间通信

55. 多进程编程

本节目标:学会用 Python 启动多个进程执行任务,掌握 ProcessPool 的用法,了解进程间如何通信。

写完前面的章节,你的程序还只能一件事接一件事地做。想同时干几件事?那就得请操作系统帮忙,把任务拆到多个进程里并行执行。

进程是什么

进程就是操作系统里「正在运行的程序」。你打开一个浏览器是一个进程,再打开一个播放器是另一个进程。它们互不干扰,各自占用独立的内存空间。

Python 里写多进程,不需要你懂 C 语言,标准库的 multiprocessing 模块已经把脏活累活包好了。

启动一个子进程

multiprocessing.Process 的用法和线程很像:传入一个函数和参数,调用 start() 启动,调用 join() 等待结束。

from multiprocessing import Process
import os

def run_child(name):
    print(f"子进程 {name},PID={os.getpid()}")

if __name__ == '__main__':
    print(f"父进程 PID={os.getpid()}")
    p = Process(target=run_child, args=('worker-1',))
    p.start()
    p.join()
    print("子进程已结束")
Warning

Windows 上必须在 if __name__ == '__main__': 块里创建进程,否则会报错或无限递归。macOS/Linux 虽然没这限制,但养成习惯总没错。

代码里的 args 一定要是元组。如果只有一个参数,记得写逗号:args=('worker-1',),否则 Python 会把字符串拆成单个字符传进去。

进程池 Pool

如果需要启动几十个甚至上百个进程,用 Process 一个个创建会很麻烦。Pool 就像一个有固定工位数的工厂,同时只让有限个进程干活,其他的排队等空位。

from multiprocessing import Pool
import os, time, random

def long_task(n):
    print(f"任务 {n} 在进程 {os.getpid()} 开始")
    time.sleep(random.random() * 2)
    print(f"任务 {n} 完成")
    return n * n

if __name__ == '__main__':
    with Pool(4) as p:
        results = p.map(long_task, range(8))
    print("全部结果:", results)

上面的 Pool(4) 表示最多同时跑 4 个进程。p.map() 会把可迭代对象里的元素挨个传给目标函数,结果按顺序收集成列表。

如果想异步提交、不等结果继续干别的,用 apply_async

if __name__ == '__main__':
    with Pool(4) as p:
        result = p.apply_async(long_task, args=(10,))
        print("我先干别的...")
        print("结果:", result.get())  # get() 会阻塞,直到结果返回
Tip

with 管理 Pool 最省心。退出 with 块时,池子会自动 close()join(),不用你手动收拾。

进程间通信

每个进程有独立的内存空间,变量不共享。想让它们交换数据,得借助操作系统提供的通道。multiprocessing.Queue 是最简单的方案之一。

from multiprocessing import Process, Queue
import time

def writer(q):
    for item in ['A', 'B', 'C']:
        q.put(item)
        print(f"写入: {item}")
        time.sleep(0.5)

def reader(q):
    while True:
        item = q.get()
        if item is None:
            break
        print(f"读取: {item}")

if __name__ == '__main__':
    q = Queue()
    pw = Process(target=writer, args=(q,))
    pr = Process(target=reader, args=(q,))
    pw.start()
    pr.start()
    pw.join()
    q.put(None)  # 发一个结束信号
    pr.join()

Queue 内部自动处理了锁和同步,你可以放心地在多个进程间读写。如果数据量大,还可以用 Pipe,它建立的是两个进程之间的双向通道,速度更快。

Note

Windows 上进程间传递数据需要经过 pickle 序列化。如果对象无法被 pickle(比如某些数据库连接、lambda 函数),就会报错。遇到这种情况,传简单数据,或者改用其他通信方式。

小结

  • Process 适合启动少量子进程,控制粒度细。
  • Pool 适合批量任务,自动管理进程数量和调度。
  • Queue / Pipe 让进程之间安全地交换数据。
  • 多进程能绕过 Python 的 GIL,真正实现多核并行。

来源:参考了 runoob「Python3 多线程」、liaoxuefeng「14.1. 多进程」等,改写后所得。