Answers:
“打开文件”的限制并不仅仅针对文件。这是对单个进程一次可以使用的内核句柄数量的限制。从历史上看,程序通常只能打开很多文件,因此这被称为对打开文件数量的限制。有一个限制可以防止进程说,打开很多文件而无意间忘记关闭它们,这最终会导致系统范围的问题。
套接字连接也是内核句柄。因此,出于相同的原因,存在相同的限制-进程可能会打开网络连接而忘记关闭它们。
如注释中所述,在类似Unix的系统中,内核句柄通常称为文件描述符。
shutdown(2)
syscall,但是对文件却没有,并且无法使用套接字从套接字读取cat
-这就是netcat
创建原因。我会说(幸运的是)类Unix内核中的套接字在I / O方面的行为类似于文件,但相似之处到此就结束了。(说实话,我也想听听有Plan 9经验的人,因为我听说他们对这些事情的统一程度远胜于传统的unices)。
究其原因,为什么TCP / IP套接字使用文件描述符的是,当套接字接口最初设计和实施(在BSD Unix的,于1983年),它的设计者认为,网络连接是类似于一个文件-你可以read
,write
和close
两个,并且非常适合Unix的“一切都是文件”的想法。
其他TCP / IP网络堆栈实现不一定与他们操作系统的文件I / O子系统集成,例如MacTCP。但是由于BSD套接字接口非常流行,因此即使其他实现也选择使用类似Unix的功能来复制套接字API,因此在没有其他方式的系统上,您将获得“文件描述符”,仅用于TCP / IP通信有文件描述符。
您问题的另一部分是为什么会有限制?这是因为实现文件描述符查找表的最快方法是使用数组。从历史上看,限制是硬编码到内核中的。
以下是Unix版本7(1979)中的代码,每个进程使用硬编码限制20个文件描述符:
相比之下,Linux为进程的文件描述符表动态分配空间。绝对限制默认为8192,但您可以将其设置为任意值。我的系统在中列出191072 /proc/sys/fs/file-max
。
alloc_fdtable()
struct fdtable
#define NR_FILE 8192
尽管Linux中不再存在绝对限制,但是我们不想让程序发疯,因此管理员(或分发打包程序)通常会设置资源限制。看一看/etc/security/limits.conf
,还是跑ulimit -n
。