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

Python中ProcessPoolExecutor从头执行代码而非指定函数的问题

问题分析与解决方案

核心原因

在Windows系统中,concurrent.futures.ProcessPoolExecutor采用spawn机制创建子进程:每个子进程都会重新加载你的整个Python脚本。这就导致脚本中所有不在函数/类定义内的顶层代码(包括os.mkdir("output")),会被每一个子进程重复执行——多个进程同时尝试创建同一个output目录,自然会抛出「文件已存在」的错误。这不是concurrent.futures的Bug,而是跨平台多进程的标准行为。

修复步骤

1. 用if __name__ == '__main__':包裹主逻辑

这是Python多进程编程的必备写法,能确保只有主进程会执行初始化、创建进程池等操作,子进程导入脚本时会跳过这部分代码。

2. 修正代码中的其他错误

  • glob.glob("../project/temp/")无法匹配任何文件,需要改成glob.glob("../project/temp/*")(匹配目录下所有文件)
  • OpenCV处理后的灰度图是numpy数组,没有save方法,需用cv2.imwrite完成保存
  • 清理output目录时,glob.glob("output")只能匹配目录本身,要改成glob.glob("output/*")来遍历目录内的文件

修正后的完整代码

import glob
import concurrent.futures
import cv2
import os

def convert_this(filename):
    # 读取图片
    img = cv2.imread(filename)
    if img is None:
        print(f"无法读取文件: {filename}")
        return
    # 转为灰度图
    res = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
    # 提取文件名,避免路径层级问题
    basename = os.path.basename(filename)
    # 保存到output目录
    cv2.imwrite(f"output/{basename}", res)

if __name__ == '__main__':
    try:
        # 创建output目录(仅主进程执行),exist_ok=True避免目录已存在时报错
        os.makedirs("output", exist_ok=True)
        with concurrent.futures.ProcessPoolExecutor() as executor:
            files = glob.glob("../project/temp/*")
            executor.map(convert_this, files)
    except Exception as e:
        print("Encountered Error!")
        print(e)
        # 清理output目录下的文件
        filelist = glob.glob("output/*")
        for f in filelist:
            os.remove(f)
        # 仅当目录为空时删除
        if not os.listdir("output"):
            os.rmdir("output")

内容的提问来源于stack exchange,提问作者rareguy

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.26 07:36:20