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

如何让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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.21 17:36:15