Python multiprocessing Pool未启动多进程的排查求助
我尝试使用Python的multiprocessing.Pool创建多进程:定义工作函数dummy_proc,编写do_stuff函数初始化processes=12的Pool并调用starmap执行任务。将do_stuff导入脚本执行后,通过htop监控发现仅创建了一个进程。任务对(pairs)约有600万条,尝试设置chunksize为任务数除以进程数也无效。运行环境为Rocky Linux release 8.9(Green Obsidian)的HPC集群。
1. 未正确保护主模块入口
在Python多进程编程中,必须用if __name__ == '__main__':包裹启动代码,否则子进程启动时会重新执行整个模块的代码,导致进程池无法正确初始化,最终只有主进程在运行。
修复代码示例:
from multiprocessing import Pool def dummy_proc(a, b): # 你的工作逻辑 return a + b def do_stuff(pairs): with Pool(processes=12) as pool: chunksize = max(1, len(pairs) // 12) results = pool.starmap(dummy_proc, pairs, chunksize=chunksize) return results if __name__ == '__main__': # 加载600万条pairs数据的逻辑 pairs = [(i, i+1) for i in range(6000000)] do_stuff(pairs)
2. HPC集群资源限制
HPC集群通常通过作业调度系统(如Slurm)限制每个任务的CPU核心数。如果你的作业仅申请了1个核心,即使设置processes=12,系统也不会允许创建更多进程。
解决方法:
检查你的作业提交脚本,确保申请了足够的CPU核心。例如Slurm脚本中需添加:
#SBATCH --cpus-per-task=12
确保集群为你的任务分配了12个CPU核心。
3. Chunksize设置不合理
如果chunksize过大,会导致第一个子进程被分配大量任务,其他子进程处于等待状态,htop暂时只显示单个进程在工作。600万任务除以12得到的50万chunk,若dummy_proc执行极快,问题不大;但如果工作函数执行耗时,需要减小chunksize让任务更快分发。
调整示例:
results = pool.starmap(dummy_proc, pairs, chunksize=10000)
更小的chunksize能让进程池快速将任务分配给所有12个工作进程。
4. 多进程启动方式异常
Linux下multiprocessing默认使用fork方式,但部分HPC环境可能因权限、环境变量或系统配置问题,导致fork无法正常创建子进程。可尝试切换为spawn或forkserver启动方式。
设置启动方式示例:
from multiprocessing import Pool, set_start_method def dummy_proc(a, b): return a + b def do_stuff(pairs): with Pool(processes=12) as pool: results = pool.starmap(dummy_proc, pairs, chunksize=10000) return results if __name__ == '__main__': set_start_method('spawn') pairs = [(i, i+1) for i in range(6000000)] do_stuff(pairs)
注意:spawn方式会重新启动Python解释器,需确保所有工作函数和数据均可序列化。
内容的提问来源于stack exchange,提问作者Debajyoti Sengupta

