运行简单示例时遭遇Multiprocessing错误,寻求解决方案
我之前在Windows环境下用multiprocessing时也踩过几乎一模一样的坑,结合你说的在cmd、Spyder、Jupyter都出问题的情况,大概率是进程启动机制或者交互式环境的特殊限制导致的,咱们一步步来排查解决:
1. 必须加上if __name__ == '__main__':防护
这是Windows系统下使用multiprocessing的核心要求——Windows没有fork机制,子进程会重新导入整个主模块,如果没有这个防护,子进程会再次执行启动代码,无限创建新进程,直接导致你说的“无限循环进程”问题。
哪怕是测试简单函数,也得严格遵守这个规则,示例代码:
import multiprocessing def test_func(num): return num * 2 if __name__ == '__main__': # 创建进程池并执行 with multiprocessing.Pool(2) as pool: results = pool.map(test_func, [1, 2, 3]) print(results)
⚠️ 特别提醒:Spyder和Jupyter这类交互式环境,这个防护的作用会被弱化,因为它们的主模块命名空间本来就是动态的,子进程可能无法正确识别__name__,后续我会说针对这些环境的特殊处理。
2. 排查AttributeError的具体诱因
你提到还触发了AttributeError,大概率和对象序列化或者环境变量污染有关:
- 避免用lambda函数或者未被正确序列化的对象作为进程目标:multiprocessing默认用pickle序列化数据,lambda、类的内部方法(未实现
__reduce__)都无法被pickle识别,会直接抛出AttributeError。如果必须用这类对象,建议把逻辑封装成顶层函数,或者使用支持更丰富序列化的库(比如pathos,它用dill替代pickle)。 - 重启Spyder/Jupyter的控制台:交互式环境容易残留旧的进程或变量,导致子进程调用时找不到预期的对象。试试关闭当前控制台,新开一个再运行代码。
3. 针对不同环境的特殊处理
Jupyter Notebook/Lab
Jupyter的交互式环境对multiprocessing的支持有限,子进程无法正确继承主模块的函数定义,推荐两种解决方式:
- 把并行逻辑封装成独立函数,并用
spawn启动方式:import multiprocessing as mp def run_parallel(input_list): # 把worker函数放在内部,确保子进程能识别 def worker(item): return item + 5 # 指定spawn启动方式,避免环境冲突 ctx = mp.get_context('spawn') with ctx.Pool() as pool: return pool.map(worker, input_list) # 调用测试 run_parallel([10, 20, 30]) - 把需要并行的函数放到单独的
.py文件中,然后在Jupyter里导入调用,这样子进程就能正确找到函数定义。
Spyder
Spyder的IPython控制台默认可能会用fork启动进程(Windows下实际还是spawn,但命名空间会有问题),可以做以下设置:
- 打开Spyder的「工具」→「偏好设置」→「IPython控制台」→「高级设置」,把「启动新的进程时使用的方法」改成
spawn; - 运行代码前,点击控制台上方的「重启内核」按钮,清除残留状态。
CMD命令行
确保你是用python your_script.py直接运行脚本,而不是进入Python交互式shell后用import your_script执行——后者同样会触发重复导入,导致无限循环。
4. 用极简代码验证环境
如果以上方法都没用,先运行这个绝对极简的测试脚本,排查是环境问题还是代码问题:
import multiprocessing import time def simple_worker(): print(f"子进程PID: {multiprocessing.current_process().pid}") time.sleep(1) return "执行完成" if __name__ == '__main__': print(f"主进程PID: {multiprocessing.current_process().pid}") p = multiprocessing.Process(target=simple_worker) p.start() p.join() print(f"子进程退出码: {p.exitcode}")
- 如果这个脚本能正常输出PID和退出码,说明你的Python环境没问题,问题出在你原来的代码里(比如隐藏的依赖、未序列化的对象);
- 如果还是出问题,那可能是Python的multiprocessing库损坏,或者有杀毒软件/防火墙拦截了子进程创建,试试重装Python或者暂时关闭安全软件测试。
内容的提问来源于stack exchange,提问作者Patrick Nasser

