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

Python多进程跨文件调用异常:__name__ == '__main__'使用问题求助

解决Python多进程中__name__相关的执行问题

咱们一步步拆解你的问题,找到根源再给出可行的解决方案——核心矛盾其实出在模块导入的__name__规则和多进程启动机制的冲突上。

问题到底出在哪?

  1. 模块导入的__name__逻辑:当你在test1.py里导入test2.py时,test2.py里所有顶级代码(不在函数/类内的代码)都会被执行一遍,但此时test2.py的__name__变量会被设为'test2'——只有直接运行的那个模块(也就是你执行的test1.py),它的__name__才是'__main__'。
  2. Windows多进程的特殊坑:如果你用的是Windows系统,multiprocessing默认用spawn方式启动子进程,子进程会重新导入你的主模块(test1.py),如果进程创建逻辑没被__name__ == '__main__'保护,就会导致子进程再次执行创建进程的代码,陷入无限递归直接报错。
  3. 你的代码结构矛盾:如果把进程池创建放在test2.py的__name__ == '__main__'块里,那test1.py调用call()时这个块根本不会执行;如果直接把进程池创建写在call()里且没加保护,Windows下就会触发重复导入的问题。

修正后的代码方案

我给你两种可行的调整方式,你可以根据需求选择:

方案1:让主模块(test1)负责进程池创建(推荐跨平台)

这种方式最稳妥,符合多进程的最佳实践:

test2.py

import multiprocessing as mp

# 全局变量
in1 = 0
in2 = 0

def cube(x):
    # 注意:子进程会复制父进程的全局变量,但修改不会同步回父进程
    return x ** 3

def call(a, b):
    global in1, in2
    in1 = a
    in2 = b

def get_task_range():
    global in1, in2
    return range(in1, in2)

test1.py

import test2
import multiprocessing as mp

if __name__ == '__main__':
    # 设置test2里的全局变量
    test2.call(0, 7)
    # 在主模块的__name__保护下创建进程池,避免Windows子进程重复执行
    with mp.Pool() as pool:
        results = pool.map(test2.cube, test2.get_task_range())
        print(results)

方案2:在test2的call函数里创建进程池(需主模块配合保护)

如果一定要把进程池创建逻辑放在test2.py的call()里,那必须确保主模块的调用被__name__保护:

test2.py

import multiprocessing as mp

in1 = 0
in2 = 0

def cube(x):
    return x ** 3

def call(a, b):
    global in1, in2
    in1 = a
    in2 = b
    
    # 这里不用加__name__判断,因为触发这个函数的主模块已经做了保护
    with mp.Pool() as pool:
        results = pool.map(cube, range(in1, in2))
        print(results)

test1.py

import test2

if __name__ == '__main__':
    # 必须把调用放在这里,避免Windows子进程重复执行这段代码
    test2.call(0, 7)

几个关键提醒

  • 全局变量的局限性:多进程中,子进程是独立的内存空间,会复制父进程的全局变量,但子进程对全局变量的修改不会影响父进程。如果需要共享状态,得用mp.Manager、mp.Value这类多进程专用的共享机制,别用普通全局变量。
  • 跨平台兼容性:哪怕你用的是Linux/macOS(用fork方式启动子进程,不会重新导入模块),也建议始终用__name__ == '__main__'保护进程创建逻辑,这样代码在Windows上也能正常运行。
  • 模块导入的副作用:别在模块的顶级代码里写进程创建、文件读写这类操作,它们会在模块被导入时执行,很容易引发意外问题。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.26 10:49:32