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
# 线程池执行并显示进度条,线程数为 10with 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 对比。