多进程编程
本教程共 70 篇 · 第 55 篇 · 更新于 2026-07-22 · 约 4 分钟阅读
55. 多进程编程
本节目标:学会用 Python 启动多个进程执行任务,掌握
Process和Pool的用法,了解进程间如何通信。
写完前面的章节,你的程序还只能一件事接一件事地做。想同时干几件事?那就得请操作系统帮忙,把任务拆到多个进程里并行执行。
进程是什么
进程就是操作系统里「正在运行的程序」。你打开一个浏览器是一个进程,再打开一个播放器是另一个进程。它们互不干扰,各自占用独立的内存空间。
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("子进程已结束")
WarningWindows 上必须在
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,它建立的是两个进程之间的双向通道,速度更快。
NoteWindows 上进程间传递数据需要经过
pickle序列化。如果对象无法被 pickle(比如某些数据库连接、lambda 函数),就会报错。遇到这种情况,传简单数据,或者改用其他通信方式。
小结
Process适合启动少量子进程,控制粒度细。Pool适合批量任务,自动管理进程数量和调度。Queue/Pipe让进程之间安全地交换数据。- 多进程能绕过 Python 的 GIL,真正实现多核并行。
来源:参考了 runoob「Python3 多线程」、liaoxuefeng「14.1. 多进程」等,改写后所得。