threadpoolexecutor 不提供连接池功能,需配合 requests.session 或数据库连接池使用;http 请求应复用 session 实例,数据库连接需线程隔离或专用池管理,避免连接泄漏与争用。

ThreadPoolExecutor 本身不提供连接池功能
直接用 ThreadPoolExecutor 并不能自动复用网络连接(比如 HTTP 连接或数据库连接),它只负责线程的生命周期和任务调度。如果你在发大量 HTTP 请求或连数据库,每个任务里自己新建 requests.Session() 或 sqlite3.connect(),那连接是各自独立创建、用完即关的——这会触发频繁握手、TLS 协商、连接池争抢,反而拖慢整体吞吐。
HTTP 场景下:Session + ThreadPoolExecutor 才是正确组合
高频 HTTP 请求必须靠 requests.Session() 复用底层 TCP 连接,再交给线程池并发执行。关键点是:Session 实例不能在每个任务里重建,得提前创建并传入或通过闭包共享。
SkillSub Pro - Python 题解与代码注释双功能技能功能概述SkillSub Pro - Python 题解与代码注释双功能技能是一项面向实际任务的技能,主要用于SkillSub Pro 是一个 Python 题解生成与代码注释的 双功能合体技能 ,专为学生、算法学习者和开发者设计;✅ 一个技能,两种用途 :;核心要点📝 题解模式 :输入题目/题号,自动生成完整 Python 题解(含详细注释、解题思路、复杂度分析);💬 注释模式 :输入 Python 代码,自动添加详细中。它将相关步骤、
- 错误写法:
def fetch(url): return requests.get(url)—— 每次都新建 Session,连接不复用 - 正确写法:初始化一个全局
session = requests.Session(),再让所有任务共用它;或用functools.partial绑定 session 到函数 - 注意线程安全:
requests.Session是线程安全的,但它的mount()配置(如自定义 adapter)需在共享前完成,运行时不要改 - 如果需要不同配置(如带不同 header 的请求),别复用同一个 Session,应按组划分多个 Session 实例
数据库场景下:别把 connect() 放进 submit() 里
像 sqlite3.connect() 或 psycopg2.connect() 这类调用,放在 executor.submit() 里执行,等于每个线程都建新连接,容易打满数据库连接数或触发锁竞争。
- SQLite:单文件数据库本身不支持多线程并发写,即使用了线程池也得加
check_same_thread=False,且写操作仍需串行化(推荐用queue.Queue控制写入顺序) - PostgreSQL/MySQL:用
threading.local()为每个线程绑定专属连接,或更稳妥地用SQLAlchemy的create_engine(pool_pre_ping=True)自动管理连接池 - 绝对避免:
executor.submit(lambda: sqlite3.connect("db.db").execute(...))—— 连接对象跨线程传递可能崩溃
超时、异常与连接泄漏的实际处理
线程池不会自动帮你回收未关闭的连接。常见泄漏点在于:任务抛异常后没走 finally 关闭资源,或忘了调用 session.close()。
- HTTP:用
with requests.Session() as s:不可行——Session 必须跨任务复用,所以得显式在程序退出前调用session.close() - 数据库:若用
threading.local()存连接,需配合atexit.register()或weakref.finalize()清理 - 设置
max_workers要谨慎:设太大可能压垮远端服务或触发连接数限制;建议从min(32, os.cpu_count() + 4)开始调优 - 捕获异常时注意:
concurrent.futures.TimeoutError和底层网络异常(如requests.exceptions.ConnectionError)要分开处理,前者说明任务卡住,后者说明连接失败
Python免费学习笔记(深入):立即使用
在学习笔记中,你将探索 Python 的核心概念和高级技巧!










