在我的一个小脚本中,我启动一个 shell,然后将其上的 RLIMIT_NPROC 设置为一些小数字,例如 5,使用限制
然后,我尝试执行一个仅包含以下内容的 shell 脚本:
#!/bin/bash
echo hi
sleep 3
通过标准输入发送“./test.sh\n”并等待结果。同时,我用来ps --ppid <somepid> -o pid=
列出第一个的子 PID。
这总是失败并出现错误bash: fork: retry: No child processes
。我尝试将限制设置为 RLIM_INFINITY 以查看创建了多少个子进程,但只列出了一个(自然是 shell 处理 test.sh)。
如何正确限制子进程的数量(或者更一般地说,限制某种分叉炸弹)?我了解 cgroup 和其他类似的替代方案,但我试图写这个来学习,这种行为确实让我感到困惑。
我认为这可能是由于 RLIMIT_NPROC 的文档指出它限制了“最大进程数(或者,更准确地说,在 Linux 上,线程)”和创建的大量线程,但是只有当我将 RLIMIT_NPROC 增加到 500 时,该程序才可以工作或者这样,这似乎不太合理。
如果此行为是意外的,则可能是编码错误,在这种情况下,我将尝试清理测试代码以发布在此处。
答案1
RLIMIT_NPROC 不控制进程可以拥有的子进程的数量。
它控制着进程的总数用户可以有。更具体地说,由于它是每个进程设置,因此当进程调用 fork()、clone()、vfork() 等时,该进程的 RLIMIT_NPROC 值将与全部的该进程父进程的进程计数用户,而不是该进程拥有的子进程的数量。
答案2
我理解手册页getrlimit(2)
说它限制了线程(此处不相关)可以作为真实用户运行。
我不确定我明白你在做什么,所以请耐心等待。您启动一个程序,该程序采用您列出的脚本,并将其作为子脚本运行。同时你跑去ps
检查 PID 吗?
用户正在运行的 shell 肯定是一个,启动脚本的程序是另一个,然后脚本正在运行,ps 使 5 个。如果现在 ps 尝试启动一个线程用于其自己的内部目的,它将由于限制而失败至 5 个进程。
你所描述的看起来像是某种实验,看看如何做某事。你真正想解决什么问题?如果不知道那是什么,我们确实无法提出更好的替代方案(或告诉您如何做您想做的事情)。