Linux下Jupyter Notebook调用subprocess结果与终端不一致的原因
差异原因说明
这个现象和subprocess模块的运行逻辑无关,本质是不同启动路径下的Python进程,从父进程继承到的RLIMIT_NOFILE(进程可打开文件描述符数量的软限制)配置不一致。
- 你在交互式终端执行
ulimit -n返回1024,是当前登录shell加载了/etc/security/limits.conf、shell rc文件(如~/.bashrc、~/.zshrc)里的ulimit配置后,自身进程持有的软限制值。此时你在终端内手动启动Python解释器,Python作为shell的子进程,会完整继承shell的所有资源限制配置;后续你通过subprocess启动的子shell进程,又会继承Python进程的限制,所以最终拿到的结果始终是1024。 - Jupyter Notebook的进程通常不是从你当前打开的交互式shell启动的:不管是通过systemd注册的后台服务、桌面环境的启动图标、还是远程服务器上的jupyterhub托管进程,它的父进程都不是你手动操作的交互式shell,自然不会继承你当前shell里设置的1024软限制。这类非交互式启动场景下的资源限制由启动它的父进程决定——systemd服务有自己的默认资源限制参数、桌面环境也有全局的默认ulimit配置,你观察到的4096就是Jupyter主进程在启动时拿到的默认
RLIMIT_NOFILE软限制值。 subprocess创建子进程时,默认会完全复制父进程的资源限制配置,所以你在Jupyter环境下调用subprocess执行ulimit -n,拿到的自然是Jupyter主进程持有的4096,和你本地交互式shell里的配置没有任何关联。同理你直接用resource模块查询到的也是当前Python进程自身的限制值,出现差异完全符合进程资源的继承逻辑。
验证与调整方式
你可以在两个环境分别运行如下代码,确认进程的继承关系和限制值:
import os import resource print(f"当前Python进程PID: {os.getpid()}") print(f"父进程PID: {os.getppid()}") soft_limit, hard_limit = resource.getrlimit(resource.RLIMIT_NOFILE) print(f"当前打开文件数软限制: {soft_limit},硬限制: {hard_limit}")
终端启动的Python会显示父进程为你当前使用的shell(bash/zsh等),软限制为1024;Jupyter环境下父进程通常为systemd、桌面管理器进程或jupyterhub相关进程,软限制为4096。
如果需要让Jupyter环境的打开文件数限制和终端一致,可选择两种方案:
- 直接在已经配置好ulimit的交互式终端中执行
jupyter notebook命令启动服务,此时Jupyter会继承当前shell的1024软限制。 - 如果是通过systemd托管的Jupyter服务,修改对应service文件中的
LimitNOFILE参数为1024,重载systemd配置后重启服务即可生效。
内容的提问来源于stack exchange,提问作者Robert Wilson
相关产品推荐
相关产品推荐

