问题: 多线程和多进程的适用场景,简单举例?

👇 点击展开/折叠 面试背诵模板(建议先背这个) 多线程适用于 I/O 密集型任务,多进程适用于 CPU 密集型任务。I/O 密集型指网络请求、文件读写、数据库查询等,I/O 操作时线程会释放 GIL,等待期间 CPU 可调度其他线程,实现并发。CPU 密集型指复杂数学计算、图像处理、视频编解码等,计算期间 GIL 持续持有,多线程无法利用多核,需用多进程绕过 GIL,实现真正的并行计算。此外多线程共享内存、切换轻量但受 GIL 限制;多进程独立内存、真并行但切换开销大。
---

场景一:I/O 密集型 → 多线程(示例:批量网络请求)

假设需要同时请求 10 个不同的 API 接口获取数据,每个请求耗时约 2 秒(等待网络响应)。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
import threading
import requests
import time

urls = ["https://api.example.com/1", "..."]

def fetch(url):
print(f"请求 {url}")
resp = requests.get(url) # I/O 等待,线程释放 GIL
print(f"完成 {url}")

threads = [threading.Thread(target=fetch, args=(url,)) for url in urls]
for t in threads: t.start()
for t in threads: t.join()

# 总耗时 ≈ 2 秒(并发),而非 20 秒(串行)

场景二:CPU 密集型 → 多进程(示例:大量数值计算)

计算 1 亿次平方运算,需要充分利用多核 CPU 处理能力。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
from multiprocessing import Process, cpu_count
import time

def heavy_compute(n):
while n > 0:
n ** 0.5
n -= 1

# 在 8 核 CPU 上启动 8 个进程
processes = [Process(target=heavy_compute, args=(10_000_000,)) for _ in range(cpu_count())]
for p in processes: p.start()
for p in processes: p.join()

# CPU 使用率拉满,总耗时 ≈ 单进程耗时的 1/8

场景选型速查表

任务类型 特征描述 推荐方案 原因
网络爬虫 大量 HTTP 请求,等待响应 多线程 / 协程 I/O 等待释放 GIL,切换开销小
文件批量读写 读取多个大文件 多线程 磁盘 I/O 等待期间释放锁
Web 服务(Flask/Django) 处理请求,查数据库 多线程(配合异步) 高并发 I/O 密集场景
图像/视频处理 像素级变换、编解码 多进程 CPU 密集计算,需绕开 GIL
机器学习训练 矩阵乘法、梯度计算 多进程 充分利用多核 CPU/GPU
数据处理(Pandas) 大量数据聚合运算 多进程 Pandas 内部也使用多进程加速
定时任务调度 同时执行多个脚本 多进程 隔离性要求高,避免互相影响

Python 并发层级的横向对比

维度 多线程 多进程 协程(asyncio)
并行能力 ❌ 受 GIL 限制 ✅ 真正并行 ❌ 单线程并发
切换开销 中等(系统线程切换) 高(进程上下文切换) 极低(用户态切换)
内存占用 低(共享内存) 高(独立内存,数据副本) 极低
通信难度 简单(共享变量+锁) 复杂(需序列化+IPC) 简单(共享变量,无锁)
适用场景 I/O 密集型 CPU 密集型 高并发 I/O(海量连接)
典型库 threading, concurrent.futures multiprocessing asyncio, aiohttp

一句话选型口诀

I/O 用线程,计算用进程,海量连接用协程。