文章目录

  • 【关于作者】
  • 1.文件描述符FD
  • 2.文件描述符的工作流程
  • 3.文件描述符限制


【关于作者】

关于作者,我目前蚂蚁金服搬砖任职,在营销投放领域工作了多年,目前在专注于内存数据库相关的应用学习

1.文件描述符FD

在linux操作系统中,将一切都抽象成了文件,包括普通文件、目录文件、套接字等。并为这些抽象的文件提供了一些统一的接口,方便应用程序调用

那么应用程序对于linux操作系统中打开的文件或者读取的文件该如何处理呢?

这里就引入了文件描述符,通过文件描述符我们能够定位到具体的文件,也能够基于文件描述符相关的元信息获得文件的相关信息

句柄:句柄可以理解为windows下的文件描述符

文件描述符:File descriptor 简称fd,当应用程序打开/新建一个文件时,内核会返回给应用程序一个文件描述符对应这个打开/创建的文件,fd本质是一个非负整数,是一个索引值,对应于该应用程序所维护该进程所打开的文件记录表中元素的索引值。

2.文件描述符的工作流程

系统建了三个表用于维护文件描述符:

  1. 进程级的文件描述符表:记录了当前应用所打开/创建的文件对应于系统文件描述符表的地址(也就是说记录了当前文件的偏移量),然后每个fd相当于该表中元素的索引地址,所以该表类似于一个记录了文件偏移量的数组,而fd的值是该数据的下标
  2. 系统级的文件描述符表(file table):所有进程共享该表,每一个表项是对file结构体的描述,其中包含当前文件位置,引用计数(即当前指向该表项的描述符表项数)
  3. 文件系统的i-node表:同文件表一样,所有的进程共享这张 v-node 表。每个表项包含 stat 结构中的大多数信息,包括 st_mode 和 st_size 成员。

android文件描述符 守护进程 文件描述符fd_linux

android文件描述符 守护进程 文件描述符fd_android文件描述符 守护进程_02

从上述图片,我们能够清晰的看出操作系统所维护的这三个表之间的关系,针对上图不同的fd指向了同一文件句柄,我们如下分析

  1. 同一进程A,不同fd指向了同一文件句柄[23]
    使用dup函数即可实现
  2. 不同进程AB,不同fd指向了同一文件句柄[73]
  • 进程AB是父子进程关系
  • A、B中某个进程通过UNIX域套接字将一个打开的文件描述符传递给另一个进程
  1. 不同进程AB,不同fd,不同文件句柄,但是句柄指向i-node表的相同条目
    不同进程对同一文件(filename)调用open函数就会这样

针对上述三个结构体的创建过程总结如下:

  1. 每创建一个进程,就会为其分配一个文件描述表,在进程task_struct中会有文件描述表file_struce的指针
  2. 每次调用open或create(内部其实还是open),都会对新打开的文件file结构体(也就是系统fd表的表项目及进程fd表的表项,open函数中的参数也会放入系统fd表的表项中)
  3. 磁盘中每个文件都对应一个i-node,每一个文件表项都会指向一个文件的i-node,表项多对一于i-node

文件描述符的唯一性:进程+文件描述符fd

3.文件描述符限制

理论来说内存越大,可打开的文件描述符数量就越多,但是实际情况是内核会有系统级限制,以及用户级限制,不让某一个应用程序进程消耗掉所有的文件资源,可以使用ulimit -n 查看