Python ThreadPoolExecutor如何串行执行process_csv任务避免多文件OLE错误
解决方案
报错根本原因:Win32COM 操作 Excel 采用单线程公寓(STA)模型,不支持多线程同时操作 Excel 实例,并发打开模板文件时就会触发 OLE error 0x800ac472 错误。你可以通过以下两种方案实现
process_csv任务串行执行,且不影响两个常驻任务运行:
方案1:互斥锁实现串行(改动最小)
利用线程互斥锁保证同一时间只有一个 process_csv 任务进入核心执行逻辑,无需调整原有线程池配置:
- 首先在实例/全局作用域初始化线程锁:
import threading # 初始化仅作用于process_csv的互斥锁 self.process_csv_lock = threading.Lock()
- 改造
process_csv方法,最外层增加锁逻辑:
def process_csv(self, file_path): # 锁会阻塞后续任务,直到上一个持有锁的任务执行完成释放 with self.process_csv_lock: # 此处保留你原有process_csv的全部逻辑,包括win32com操作Excel的代码 excel = win32com.client.Dispatch("Excel.Application") wb = excel.Workbooks.Open(模板文件路径) # 后续填充、转PDF等逻辑
方案2:独立单线程池隔离执行(逻辑更清晰)
单独创建一个单线程的线程池专门处理 process_csv 任务,和原有常驻任务的线程池完全隔离:
- 新增专用单线程池:
from concurrent import futures # 原有max_workers=5的线程池保留,仅用于提交两个常驻任务 self.common_thread_pool = futures.ThreadPoolExecutor(max_workers=5) # 新增max_workers=1的线程池,专门处理process_csv任务,天然保证串行执行 self.csv_process_pool = futures.ThreadPoolExecutor(max_workers=1)
- 调整任务提交逻辑:原监听文件新增后提交任务的代码,从
self.common_thread_pool.submit(self.process_csv, a_string)改为self.csv_process_pool.submit(self.process_csv, a_string)即可。
通用优化建议
两种方案都建议在process_csv执行完成后显式释放Excel COM对象,避免资源泄漏导致后续报错:
# Excel操作结束后新增释放逻辑 wb.Close(SaveChanges=1) # 按需选择是否保存修改 excel.Quit() del excel
内容的提问来源于stack exchange,提问作者cmccall95
相关产品推荐
相关产品推荐

