Python ThreadPoolExecutor线程池深度笔记

ThreadPoolExecutor

一、线程池机制

线程池通过预先创建一组空闲线程(工作线程),维护任务队列,实现线程复用。当新任务到达时,线程池会将任务放入队列,由空闲线程自动获取执行,避免了频繁创建/销毁线程的开销

二、ThreadPoolExecutor基础用法🚀

2.1 快速入门模板

from concurrent.futures import ThreadPoolExecutor
import time

def task(n):
    print(f"处理任务 {n}")
    time.sleep(1)
    return n * n

with ThreadPoolExecutor(max_workers=3) as executor:
    futures = [executor.submit(task, i) for i in range(5)]
    results = [f.result() for f in futures]

print(f"结果: {results}")  # 输出: [0, 1, 4, 9, 16]

三、ThreadPoolExecutor 初始化参数详解

1. max_workers (核心参数)
作用:指定线程池中最大线程数
默认值:min(32, (os.cpu_count() or 1) + 4)(基于 CPU 核心数动态计算)
建议:根据任务类型调整(I/O 密集型可适当增大,CPU 密集型建议接近 CPU 核心数)
2. thread_name_prefix (可选)
作用:设置线程名称前缀,便于调试
示例:前缀为 “DownloadPool-” → 线程名称为 DownloadPool-0, DownloadPool-1…
3. initializer (可选)
作用:线程池中每个工作线程创建前,执行的初始化函数(常用于设置线程局部资源)
典型场景:初始化数据库连接、设置线程局部存储(Thread-Local Storage)
4. initargs (可选)
作用:传递给 initializer 的参数(需为元组类型)

与Java线程池对比

看到python 线程池与跟Java的线程池在创建对象时有很大不同。暴露给用户的参数太少了。
不同点有以下几点:

  1. 线程池没有最小核心线程池的概念
  2. 线程池的队列是内置的,用户不可以调整,还是无界队列,使用不当容易OOM
  3. 线程池用的工作线程是没有限制的时间,也就是说会一直阻塞获取
  4. 因为使用的是无界队列,所以也就没有了拒绝策略

接下来让我们看一下python 线程池提的接口
这是自身的的=
这是父类的
可以看到线程池对外提供了一个submit 提交任务的方法。
让我们看一下submit的处理流程。

可以看到具体的逻辑应该在_adjust_thread_count()方法中。继续追踪

接下来让我们看一下工作线程的处理逻辑。t.start() 其实运行的就是_worke函数。继续追踪

好了,到此整个提交逻辑代码就追踪完了。

五、总结:

线程池的执行主流程如下:

  1. 线程池提交任务

  2. 将任务封装成workItem对象

  3. 将workerItem对象保存到队列中

  4. 判读当前工作线程总数是否小于设置的最大工作线程
    是:创建工作线程 => start方法启动线程 => 执行_worke方法 => 调用初始化函数,进行数据初始化(只会执行一次) => 循环从队列中获取任务执行。

    否:不创建任务

备注:以上是我自己看源码理解的,如果有不对的地方,还请道友指出。

作者:wyz0923

物联沃分享整理
物联沃-IOTWORD物联网 » Python ThreadPoolExecutor线程池深度笔记

发表回复