Python 多进程【二进宫】
CPU多进程VS多线程
结果
[Thread多线程]总耗时:1.44秒 多线程几乎和串行一样慢(因为 GIL)
[Process多进程]总耗时:0.43秒 多进程是真正“并行”执行,速度直接提升 3 倍以上
代码示例
# -*- coding: utf-8 -*-
# 问题?:多线程为什么跑不快计算任务, 答案:因为GIL全局解释器锁。同一时刻只允许一个线程执行Python代码
import multiprocessing
import threading
import time
import math
def cpu_task():
total = 0
for i in range(10_000_000):
total += math.sqrt(i)
return total
if __name__ == '__main__':
# 多线程
thread_start_time = time.time()
threads = []
for _ in range(4):
t = threading.Thread(target=cpu_task)
t.start()
threads.append(t)
for t in threads:
t.join()
print(f"[Thread多线程]总耗时:{time.time() - thread_start_time:.2f}秒")
# 多进程
proces_start_time = time.time()
processes = []
for _ in range(4):
p = multiprocessing.Process(target=cpu_task)
p.start()
processes.append(p)
for p in processes:
p.join()
print(f"[Process多进程]总耗时:{time.time() - proces_start_time:.2f}秒")
烧CPU,串行VS多线程VS多进程
结果
[Serial串行]总耗时:1.45秒
[Thread多线程]总耗时:1.43秒
[Process多进程]总耗时:0.42秒 # 调用四个进程,相当于同时开了4个Python解释器
示例代码
# -*- coding: utf-8 -*-
import multiprocessing
import threading
import time
import math
# CPU 计算任务:计算密集型任务
def cpu_task():
total = 0
for i in range(10_000_000):
total += math.sqrt(i)
return total
# 串行
def run_serial():
start_time = time.time()
for _ in range(4):
cpu_task()
print(f"[Serial串行]总耗时:{time.time() - start_time:.2f}秒")
# 多线程并发
def run_threads():
start_time = time.time()
threads = []
for _ in range(4):
t = threading.Thread(target=cpu_task)
t.start()
threads.append(t)
for t in threads:
t.join()
print(f"[Thread多线程]总耗时:{time.time() - start_time:.2f}秒")
# 多进程并发
def run_processes():
start_time = time.time()
processes = []
for _ in range(4):
p = multiprocessing.Process(target=cpu_task)
p.start()
processes.append(p)
for p in processes:
p.join()
print(f"[Process多进程]总耗时:{time.time() - start_time:.2f}秒")
if __name__ == '__main__':
run_serial()
run_threads()
run_processes()
总结
进程基础用法
- start() 启动子进程
- join() 等待子进程结束
多进程使用场景
- 图像处理(Pillow图像缩放,滤镜)
- 视频编码/解码
- 模型推理
- 加密、压缩,hash哈希计算(文件校验)
- 批量数据清洗,转换,计算
多进程优缺点
| 优点 |
缺点 |
| 真正并行,能充分利用多核 CPU |
进程间内存隔离,共享数据麻烦 |
| 避开 GIL,适合 CPU 密集任务 |
启动慢,通信成本高 |
| 稳定性高,一个崩了不影响另一个 |
创建进程的开销比线程大 |
参考
https://zhuanlan.zhihu.com/p/1923366864152658874