如何让Python多进程池启动并运行自身的多进程池?
嵌套多进程池:让子进程创建自身的子进程
核心结论
默认情况下multiprocessing.Pool的子进程是守护进程,这类进程确实无法再创建子进程(会触发AssertionError: daemonic processes are not allowed to have children)。但可以通过自定义进程创建逻辑,让初始Pool的子进程变为非守护进程,从而实现嵌套创建Pool的需求。
实现方案
1. 自定义非守护进程类
继承multiprocessing.Process,强制将进程的daemon属性设为False:
from multiprocessing import Process class NonDaemonProcess(Process): def __init__(self, *args, **kwargs): super().__init__(*args, **kwargs) self.daemon = False
2. 创建使用非守护进程的Pool
基于自定义进程类,封装一个返回非守护进程Pool的函数:
from multiprocessing import Pool def non_daemon_pool(processes=None): return Pool(processes=processes, maxtasksperchild=1)
3. 修改原代码适配
将所有Pool实例替换为自定义的non_daemon_pool,即可实现嵌套进程池:
import numpy as np def do_something( num: int, data: list[int], num_procs: int = 2, ): args_list = [[val, num] for val in data] # 使用非守护进程Pool创建子进程 with non_daemon_pool(processes=num_procs) as pool: results = pool.starmap(do_another_thing, args_list) return results def do_another_thing(value1: int, value2: int): return value1 * value2 if __name__ == "__main__": # 生成示例数据集 data = [np.random.randint(0, 255, (20)) for _ in range(20)] args_list = [[i, arr] for i, arr in enumerate(data)] # 主进程使用非守护进程Pool with non_daemon_pool(processes=4) as pool: results = pool.starmap(do_something, args_list) # 打印部分结果示例 for idx, res in enumerate(results): print(f"数据集 {idx} 处理结果(前5项): {res[:5]}")
关键注意事项
- 资源控制:嵌套多进程会快速创建大量进程,需根据CPU核心数合理设置
processes参数,避免系统资源耗尽。 maxtasksperchild参数:设置为1可让子进程完成单个任务后退出,减少长期占用资源的风险,也能降低内存泄漏概率。- 替代思路:如果嵌套进程的资源管理过于复杂,可考虑在主进程创建全局大Pool,将所有子任务统一提交,避免嵌套创建Pool。
内容的提问来源于stack exchange,提问作者TheEponymousProgrammer
相关产品推荐
相关产品推荐

