Python2与Python3下multiprocessing.Process多进程Too many open files报错原因问询
问题根因
你提供的代码逻辑为逐行遍历SELLS表的2000条记录,每条都单独启动一个multiprocessing.Process进程处理,同时在所有进程全部启动完成后才统一执行join()回收资源。直接触发报错的原因是父进程在创建子进程的过程中耗尽了系统允许的单进程最大打开文件数(Unix系系统默认上限通常为1024),新建进程调用os.pipe()创建父子通信管道时无可用文件描述符,抛出OSError: [Errno 24] Too many open files。
Python2与Python3 multiprocessing模块的差异点
该问题是Python3对multiprocessing的进程控制逻辑迭代导致的,具体改动如下:
- Python2的multiprocessing仅为每个子进程创建1组通信管道,用于传递返回值和异常信息,且父进程在子进程启动完成后会立即释放冗余的管道文件描述符,2000个并发进程的总文件描述符占用刚好低于默认1024的上限,因此可以正常运行。
- Python3重构了multiprocessing的进程生命周期管理逻辑,每个Process实例创建时会新增2组管道,分别用于父子进程同步、异常回溯信息传递,同时父进程会持有所有子进程的管道文件描述符,直到对应子进程执行
join()完成回收才会释放。你代码中先全量启动2000个进程再统一回收的逻辑,会导致父进程在启动阶段需要同时持有至少4000个活跃文件描述符,直接超出系统默认上限触发报错。
修复方案
- 优先使用
multiprocessing.Pool进程池,设置和CPU核心数匹配的并发度,复用进程处理任务,从根源上避免同时创建上千个进程导致的资源耗尽问题。示例改造逻辑如下:
def GetTargetItemsAndPrice(cursor): res = cursor.execute("SELECT DISTINCT items, price FROM SELLS") tasks = res.fetchall() # 设置并发数为CPU核心数,可根据实际情况调整 with multiprocessing.Pool(processes=multiprocessing.cpu_count()) as pool: pool.starmap(RunPrice, tasks)
- 临时解决方案:执行命令
ulimit -n 65535调高当前会话的单进程最大打开文件数上限,再运行脚本即可,该方案治标不治本,不推荐生产环境使用。 - 调整进程启动逻辑:将2000个任务拆分为多批次,每启动一批进程就先执行
join()回收资源,再启动下一批,避免父进程同时持有大量文件描述符。
内容的提问来源于stack exchange,提问作者n00bz0r
相关产品推荐
相关产品推荐

