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

Python3.6执行subprocess报错Too many open files 设置ulimit无效如何解决

subprocess报Too many open files问题排查与解决

排查步骤

  • 先确认当前进程的文件描述符使用情况:执行ls /proc/<Python进程PID>/fd | wc -l统计打开的fd总数,和当前进程的ulimit上限cat /proc/<Python进程PID>/limits | grep "Max open files"对比,确认是实际使用量超过上限导致的报错。
  • 排查泄漏的fd类型:执行ls -l /proc/<Python进程PID>/fd,如果大部分fd指向pipe类型,即可确认是subprocess创建的管道资源未正确释放导致的泄漏,和你当前的代码写法直接相关。
  • 排查ulimit配置生效范围:永久配置不生效通常是因为程序启动方式的问题,/etc/security/limits.conf仅对PAM登录的会话生效,如果你是用systemd管理的服务、桌面端快捷方式启动的程序,不会读取该配置。可以临时在启动Python程序的终端先执行ulimit -n 65535再启动程序,验证是否是ulimit上限不够的问题。

核心问题原因

你当前的subprocess写法存在明确的资源泄漏风险:

  1. 仅手动关闭了stdout流,subprocess创建的stderr流、内核层面的errpipe通信管道都没有被回收。
  2. 调用terminate()杀进程后没有等待进程退出回收,会产生僵尸进程,对应的管道资源会被内核一直持有不会释放。
  3. Python3.6版本的subprocess自动回收机制不完善,手动管理资源极易出现遗漏。

解决方法

1. 替换为更安全的subprocess调用方式

优先使用subprocess.run()替代手动管理Popen,它会自动等待进程结束、回收所有关联资源,你的代码可以直接替换为如下写法:

# check参数控制是否要在进程非0退出时抛出异常,可根据自己的业务需求调整
result = subprocess.run(command1, shell=True, stdout=subprocess.PIPE, stderr=subprocess.DEVNULL, close_fds=True)
output = result.stdout.readlines()
# 不需要手动关闭流、杀进程,run方法会自动处理所有资源回收

如果必须使用Popen做异步交互,一定要用上下文管理器托管生命周期:

with subprocess.Popen(command1, shell=True, stdout=subprocess.PIPE, stderr=subprocess.DEVNULL, close_fds=True) as process:
    output = process.stdout.readlines()
# 出with作用域后会自动关闭所有流、等待进程退出,无需手动调用terminate和close方法

2. 强制关闭继承的文件描述符

所有subprocess调用都显式加上close_fds=True参数,会在子进程启动时关闭所有从父进程继承的不必要的文件描述符,避免父进程的打开文件被带到子进程中泄漏。

3. 原有写法的兜底修复

如果暂时不能重构现有代码,要在原有逻辑中补充管道回收和进程等待逻辑:

process = subprocess.Popen(command1, shell=True, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
output = process.stdout.readlines()
# 读空stderr缓存,避免缓冲区占着资源
err_output = process.stderr.read()
# 显式关闭所有打开的流
process.stdout.close()
process.stderr.close()
process.terminate()
# 等待进程完全退出,回收进程资源
process.wait()

4. 正确配置ulimit上限

如果是systemd管理的服务,修改对应的service配置文件,在[Service]段添加LimitNOFILE=65535,之后执行systemctl daemon-reload && systemctl restart <你的服务名>生效。如果是终端直接运行的脚本,可以在启动脚本的开头添加ulimit -n 65535再启动Python进程。

内容的提问来源于stack exchange,提问作者FIIIBS

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.28 05:45:03