Python多进程通过multiprocessing模块绕过全局解释器锁,让任务在多个CPU核心上真正并行执行。理解其原理和通信机制,是编写稳定并发程序的基础。

一、多进程核心原理
在Unix-like系统中,multiprocessing默认使用fork方式创建子进程,子进程复制父进程内存空间,之后各自独立运行。进程之间不共享全局变量,必须通过特定机制交换数据。
1.1 进程的创建方式
最常见的是使用Process类直接创建,也可以通过进程池统一管理。下面演示基础用法:
from multiprocessing import Process
def worker(name):
print("子进程执行:" + name)
if __name__ == "__main__":
p = Process(target=worker, args=("task-1",))
p.start()
p.join()
print("主进程结束")
1.2 进程间通信
由于进程内存隔离,可使用Queue或Pipe传递数据。Queue是线程和进程安全的先进先出结构,适合多生产者多消费者场景。
from multiprocessing import Process, Queue
def producer(q):
q.put("一条数据")
def consumer(q):
print("收到:" + q.get())
if __name__ == "__main__":
q = Queue()
p1 = Process(target=producer, args=(q,))
p2 = Process(target=consumer, args=(q,))
p1.start()
p2.start()
p1.join()
p2.join()
二、Pool进程池实战
当需要批量处理大量任务时,频繁创建销毁进程开销较大。Pool可复用固定数量的 worker 进程。
2.1 使用map批量执行
以下案例用进程池计算一组数字的平方,充分利用多核能力:
from multiprocessing import Pool
def square(x):
return x * x
if __name__ == "__main__":
data = [1, 2, 3, 4, 5]
with Pool(processes=3) as pool:
result = pool.map(square, data)
print(result)
2.2 异步提交任务
若任务耗时不一致,可用apply_async非阻塞提交,避免空闲等待。
from multiprocessing import Pool
import time
def slow_task(n):
time.sleep(1)
return n * 10
if __name__ == "__main__":
with Pool(4) as pool:
jobs = [pool.apply_async(slow_task, (i,)) for i in range(8)]
for job in jobs:
print(job.get())
三、常见注意事项
- 必须放在 if __name__ == "__main__" 中启动,防止子进程递归fork。
- 尽量用Queue或Manager共享状态,避免用普通全局变量。
- CPU密集型用多进程,IO密集型可优先考虑多线程或异步。
掌握Process、Queue与Pool三者组合,就能应对绝大多数Python多进程开发场景。
四、小结
本文从原理到代码演示了Python多进程的关键用法。实际项目中建议先抽象任务类型,再决定通信方式与池大小,才能写出高效且易维护的并发程序。