文件描述符是什么
在 Linux 系统中,一切可以看成是文件,文件可分为:普通文件、目录文件、链接文件和设备文件。文件描述符 (file descriptor) 是内核为了高效管理已经被打开的文件所创建的索引,它是一个非负整数(通常是小整数),用于指代被打开的文件。
程序刚启动的时候,0是标准输入,1是标准输出,2是标准错误,如果此时去打开一个新的文件,它的文件描述符会是3.
POSIX(Protable Operating System Interface), 是 IEEE 为要在各种UNIX操作系统上运行软件,而定义 API 的一系列互相关联的标准的总称,其正式称呼为 IEEE Std1003,国际化标准名称为 ISO/IEC 9945.
应 POSIX 标准要求,每次打开文件时(含socket)必须使用当前进程中最小可用的文件描述符号码。
文件描述符与打开的文件对应模型
文件描述符存在限制
文件描述符是系统重要的资源,内核会对其做相应的限制,一般最大打开文件数会是系统内存的10%(KB)(系统级限制),查看系统级别的最大打开文件数可以用
sysctl -a |grep fs.file-max
进行查看
内核为了不让某一进程消耗掉所有的文件资源,其也会对单个进程的最大打开文件数做默认处理(用户级限制),默认值 1024 ,使用 ulimit -n
可以查看。
在 WEB 服务器中,通过更改系统默认文件描述符最大值来优化服务器。
文件描述符和打开文件之间的关系
每一个文件描述符会与一个打开文件相对应,同时,不同的文件描述符也可能指向同一个文件。相同的文件可以被不同的进程打开,也可以被同一进程打开多次。系统为每个进程维护了一个文件描述符表,该表的值都是从0开始的,所以在不同的进程中,会看到相同的文件描述符,描述符有可能指向同一个文件,也有可能指向不同文件。
内核维护3个数据结构:1.进程级的文件描述符表 2.系统级的打开文件描述符表 3.文件系统的 i-node 表
总结
由于进程级文件描述符表的存在,不同的进程中会出现相同的文件描述符,它们可能指向同一个文件,也可能不同。
两个不同的文件描述符标志,若指向同一个打开文件句柄,将共享同一文件偏移量。因此,如果通过其中一个文件描述符来修改文件偏移量,那么另一个也会观察到变化,无论这两个文件是否属于不同进程还是同一进程,情况都一样。
文件描述符标志为进程和文件描述符所私有。对这一标志的修改不会影响同一进程或不同进程中其他文件描述符
扩展
上面只是一些简单的介绍,在 I/O 多路复用技术中,多次提到文件描述符,想弄明白它到底是个什么东西,并且在 Select 异步 I/O 环境中,还说 文件描述符的最大数量限制,所以就想了一下,文件描述符到底是什么。