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

Windows下Python concurrent.futures并发重复执行问题解决方法

问题根因
  • 首先你混淆了多线程和多进程:代码中使用的ProcessPoolExecutor是多进程池,并非多线程池。Windows系统下Python多进程默认采用spawn启动方式,和Linux/macOS默认的fork机制不同:spawn不会直接复制父进程的内存状态,而是会启动全新的Python解释器进程,重新导入执行主脚本的所有顶层(函数/类外、不受__name__判断保护)代码,以此加载目标函数、依赖变量等运行必需的资源。
  • 你当前的写法仅将进程池启动逻辑放入了if "__main__" == __name__:判断块,待处理列表生成、计时变量初始化、结果打印、结果字典初始化这些逻辑都暴露在顶层。每启动一个子进程,这些顶层代码就会被执行一次,这就是你看到重复打印、子进程中字典长度为0的原因——子进程导入脚本时__name__不是"__main__",不会进入判断块执行多进程任务逻辑,自然输出空字典、零耗时的结果。
  • 这个重复现象不是递归问题,是spawn启动机制下顶层代码未做隔离的必然结果。另外你使用的process_time()仅统计当前进程的CPU时间,不会累加子进程的CPU耗时,统计多进程任务的整体运行时间结果不准。
修复方案

核心规则:所有仅需要主进程执行的逻辑,必须全部放入if "__main__" == __name__:判断块内部,顶层仅保留导入语句、全局常量、函数/类定义这类所有进程都需要加载的公共资源。
修复后的可运行代码如下:

import concurrent.futures
from itertools import product
from time import perf_counter

# 多进程调用的目标函数属于公共定义,放在顶层供所有进程加载
def genDict(in_value):
    out_dict = {}
    out_dict[in_value] = list(in_value)
    return out_dict

# 仅主进程需要执行的逻辑,全部放入判断块内
if __name__ == "__main__":
    # 生成待处理数据集
    alphabets = ['a', 'b', 'c', 'd', 'e']
    listToProcess = [''.join(i) for i in product(alphabets, repeat=4)]
    print('待处理列表长度:', len(listToProcess))

    # 初始化结果容器、计时器
    dictResult = {}
    t1_start = perf_counter()

    # 启动多进程池执行任务
    with concurrent.futures.ProcessPoolExecutor(4) as executor:
        futures = [executor.submit(genDict, elem) for elem in listToProcess]
        # 用as_completed在任务完成时立刻获取结果,提升执行效率
        for future in concurrent.futures.as_completed(futures):
            dictResult.update(future.result())
    
    t1_stop = perf_counter()
    print(f'多进程执行耗时 = {t1_stop - t1_start} 秒')
    print('\n该打印逻辑仅在主进程运行,不会重复触发')
    print(f'结果字典长度: {len(dictResult)}')
额外说明
  • 如果你实际需要的是多线程而非多进程,将ProcessPoolExecutor替换为ThreadPoolExecutor即可。多线程共享主进程内存空间,不会重新导入脚本,Windows下也不需要__name__判断即可正常运行,不会出现重复执行问题。
  • 并行任务耗时统计推荐使用perf_counter(),它统计的是实际经过的墙钟时间,比process_time()更适合衡量并行任务的整体执行速度。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.28 11:21:42