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