skip to content
Liu Yang's Blog

Python 线程池处理 I/O 密集型任务

/ 2 min read

Updated:

在线爬取、批量调用接口这类任务,大部分时间花在等待网络返回上,属于 I/O 密集型。这种场景用线程池就能获得明显的加速,max_workers 顺便起到控制请求频率的作用。

import concurrent.futures
from tqdm import tqdm
job_list = list(range(10))
def process(x):
# 在这里实现单个任务,返回处理结果
return x**2
# 线程池执行并显示进度条,线程数为 10
with concurrent.futures.ThreadPoolExecutor(max_workers=10) as executor:
# executor.map 返回迭代器,交给 tqdm 显示进度,结果顺序与 job_list 一致
result_list = list(tqdm(executor.map(process, job_list), total=len(job_list)))

几点说明:

  • executor.map 返回结果的顺序和输入一致,不需要自己对齐。
  • max_workers 不是越大越好。对同一个接口并发太高,容易触发限流。
  • 如果任务是 CPU 密集型(例如大量计算),受 GIL 限制,线程池帮助不大,应该换成 ProcessPoolExecutor。

线程、进程和协程的更完整对比见 Python 协程与 Process / Thread 对比。