文件描述符限制(ulimit -n)的历史原因是什么

文件描述符限制(ulimit -n)的历史原因是什么

1990 年,当我第一次在 UNIX 系统上借用帐户时,文件限制达到了惊人的 1024,所以我从来没有真正认为这是一个问题。

30 年后的今天,(软)限制仅为 1024。

我认为 1024 的历史原因是它是一种稀缺资源 - 尽管我无法真正找到证据。

我的笔记本电脑的限制是(2^63-1):

$ cat /proc/sys/fs/file-max
9223372036854775807

今天我看到的数字与 1990 年的 1024 一样惊人。我的系统上的硬限制 ( ulimit -Hn) 将其进一步限制为 1048576。

但为什么要有限制呢?为什么不让 RAM 成为限制资源呢?

我在 Ubuntu 20.04(从 2020 年开始)和 HPUX B.11.11(从 2000 年开始)上运行了这个:

ulimit -n `ulimit -Hn`

在 Ubuntu 上,此限制从 1024 增加到 1048576。在 HPUX 上,它从 60 增加到 1024。在这两种情况下,内存使用情况都没有任何差异ps -edalf。如果稀缺资源不是RAM,那是什么?那么稀缺资源呢?

我从未经历过 1024 限制对我或我的用户有帮助 - 相反,这是我的用户无法解释并因此无法自行解决的错误的根本原因:考虑到他们在ulimit -n 1046576运行工作之前不会立即想到的经常神秘的崩溃。

我可以看到限制是有用的全部的进程的内存大小,因此如果它疯狂运行,不会导致整个系统崩溃。但我不明白这如何适用于文件限制。

早在 1990 年,1024 的限制(而不仅仅是一般的内存限制)在什么情况下会有帮助?而今天是否也有类似的情况呢?

答案1

@patbarron 还没有发表他的评论作为答案,而且它们真的很棒。所以对于任何寻找答案的人来说,它就在这里。

他写:

您可以查看第七版的源代码,例如(minnie.tuhs.org/cgi-bin/utree.pl?file=V7/usr/sys/h/user.h)看看最初是如何实现的。 “NOFILE”是每个进程打开文件的最大数量,它影响每个进程分配的数据结构的大小。这些结构无论是否实际使用都会占用内存。同样,主要是出于历史兴趣,因为现在不再这样做了,但这可能会提供一些关于其来源的额外背景。

另一个常量“NFILE”是整个系统(跨所有进程/用户)打开文件的最大数量,每个进程的打开文件表包含指向“files”结构的指针:minnie.tuhs.org/cgi-bin/utree.pl?file=V7/usr/sys/conf/cc。这也是一个编译时常量,用于确定系统范围内打开文件表的大小(无论是否实际使用,该表也会消耗内存)。

这说明历史上是有原因的。每个进程都会保留 NOFILE 文件描述符——无论它们是否被使用。当 RAM 不足时,您希望避免保留不使用的内存。如今,不仅 RAM 更便宜,而且预订也不再以这种方式完成。

它证实了我的观察:我找不到任何理由让你保持ulimit -n在 1024 而不是将其提高到最大值:ulimit -n $(ulimit -Hn)。仅在实际使用文件描述符时才占用内存。

答案2

据我所知,是的,文件最大内核硬限制是由于内存分配策略造成的(预先分配了 inode 结构的内存)。这种策略很常见、直观且高效(当时),并且在 DOS、Windows、Linux 和其他操作系统之间共享。

如今,我相信您看到的巨大数字是理论最大值(2 64 -1),“真实”文件最大值是在运行时分配的,可以通过 ulimit (ulimit -Hnulimit -Sn)进行设置。因此,“file-max”只是 ulimit 的一种最大值,本质上毫无意义 - 它的意思是“无论如何,直到 ulimit 耗尽 RAM”。

答案3

网络代码中用于监视文件描述符的常用函数 ,select()在许多实现中仅处理最多 1023 个文件描述符。虽然此函数在新代码中通常被认为已过时,但使用该函数的软件在处理编号较高的文件描述符时将无法正常运行。

文件描述符仅被用户进程视为整数值,并且通过假设可能的文件描述符的小固定范围并迭代整个范围检查是否每个文件描述符都被标记为要处理来实现对文件描述符集进行操作的函数。如果最大文件描述符数量太大,这最终会导致成本极高。

相关内容