Windows下Python使用multiprocessing出现RuntimeError如何解决?
错误根本原因
Windows 系统的 Python multiprocessing 模块默认使用 spawn 模式创建子进程,和 Linux 默认的 fork 模式不同:spawn 模式会启动全新的 Python 解释器,重新导入当前主模块执行,所有没有包裹在 if __name__ == '__main__' 内的顶层代码都会在每个子进程启动时重复执行,这是报错的直接诱因。
现有代码的问题
- 共享内存创建、
Manager实例初始化、全局变量定义等执行逻辑都写在if __name__ == '__main__'之外,子进程导入模块时会重复执行这些逻辑,触发进程启动冲突 - 直接将绑定了共享内存缓冲区的 numpy 数组作为参数传给子进程,
spawn模式下序列化传参会丢失共享内存的绑定关系,子进程无法正常读取共享内存数据
修复方案
将所有模块顶层的执行逻辑移入 if __name__ == '__main__' 块内,子进程通过共享内存名称主动挂载共享内存,而非直接接收 numpy 数组对象。修正后代码如下:
from multiprocessing import shared_memory import pandas as pd import numpy as np import multiprocessing # 仅保留导入语句和函数定义在模块顶层 def predict_model(shm_name, arr_shape, arr_dtype, model_list_str, forecast_period, pred_sales_all): # 子进程内主动挂载共享内存 shm = shared_memory.SharedMemory(name=shm_name) b = np.ndarray(arr_shape, dtype=arr_dtype, buffer=shm.buf) c = pd.Series(b) temp_add = model_list_str + forecast_period temp_series = c.add(model_list_str) pred_sales_all[str(temp_add)] = temp_series # 关闭当前进程的共享内存挂载 shm.close() if __name__ == '__main__': # 所有执行逻辑全部移入main保护块内 s = pd.Series(np.random.randn(50)) s = s.to_numpy() # 创建共享内存 shm_s = shared_memory.SharedMemory(create=True, size=s.nbytes) b = np.ndarray(s.shape, dtype=s.dtype, buffer=shm_s.buf) b[:] = s[:] mgr = multiprocessing.Manager() pred_sales_all = mgr.dict() forecast_period = 1000 model_list = [1, 2, 3, 4] all_process = [] for model_list_str in model_list: # 传共享内存名称、数组形状、类型参数,而非直接传绑定了缓冲区的数组 process = multiprocessing.Process( target=predict_model, args=(shm_s.name, s.shape, s.dtype, model_list_str, forecast_period, pred_sales_all) ) process.start() all_process.append(process) # 等待所有子进程执行完毕 for p in all_process: p.join() # 主进程释放共享内存,避免内存泄漏 shm_s.close() shm_s.unlink() # 输出结果验证 print(dict(pred_sales_all))
补充说明
如果后续需要将代码打包为exe可执行文件,只需在if __name__ == '__main__'块的第一行添加multiprocessing.freeze_support()即可,普通脚本运行无需添加该行。
内容的提问来源于stack exchange,提问作者Danish Xavier
相关产品推荐
相关产品推荐

