Python multiprocessing.Pool多进程日志重复条目问题排查
问题原因分析与解决
核心原因排查
从现象和代码来看,主要有两个可能的根源:
1. 任务列表存在重复文件路径
你传给p.map的doc_mp_list_xlsx列表中,大概率包含重复的x.pdf路径。multiprocessing.Pool.map会严格按列表元素逐个分发任务,只要列表里有重复条目,就会被不同Worker进程分别处理,自然生成多条对应日志。可以用这段代码快速检查重复项:
from collections import Counter path_counts = Counter(doc_mp_list_xlsx) duplicates = [path for path, count in path_counts.items() if count > 1] if duplicates: print(f"找到重复文件路径:{duplicates}")
2. Windows下spawn模式导致日志配置重复执行
Windows系统中,multiprocessing默认用spawn方式启动子进程——子进程会重新导入整个脚本,包括主进程里那段循环创建Logger的代码。这会导致每个子进程都为所有Worker的Logger添加FileHandler,最终出现同一次文件处理的日志被多个Handler写入到不同日志文件的情况,看起来像是不同Worker处理了同一个文件,但实际是日志被重复记录了。
修复方案
处理重复任务列表
清理doc_mp_list_xlsx里的重复路径,若需要保留原顺序,可用dict.fromkeys去重:
# 去重且保留原顺序 doc_mp_list_xlsx = list(dict.fromkeys(doc_mp_list_xlsx))
修复日志配置问题
把日志配置代码放到if __name__ == '__main__':块中,避免子进程重复执行配置逻辑,同时关闭Logger的日志传播,防止根Logger额外记录:
import logging import multiprocessing from utils import read_config config = read_config.config def getLogger(name): return logging.getLogger(str(multiprocessing.current_process().name)) if __name__ == '__main__': num_cores = multiprocessing.cpu_count() # 仅在主进程配置日志 for process in range(1, num_cores+1): handler = logging.FileHandler(f"{config['logging_path']}\\{process}.log") handler.setFormatter(logging.Formatter( '%(asctime)s*|*%(levelname)s*|*%(message)s*|*%(module)s*|*%(funcName)s*|*%(lineno)d*|*%(name)s')) logger = logging.getLogger(f"SpawnPoolWorker-{process}") logger.setLevel(logging.INFO) logger.addHandler(handler) # 禁止日志向上传播,避免根Logger重复记录 logger.propagate = False # 启动进程池执行任务 with multiprocessing.Pool(processes=num_cores) as p: output_mp = p.map(clean_file, doc_mp_list_xlsx)
内容的提问来源于stack exchange,提问作者Tobias
相关产品推荐
相关产品推荐

