You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.09 22:56:29