文章目录
- 1.简介
- 2. 出现的必要性
- 3. 创建FD的方法
- 4. FD的存储方式
- 5. FD 名称(cwd,memory.....\d[u|r|w])
- 6.FD TYPE
- 7. 查看FD使用情况
1.简介
FD(file descriptor):文件描述符。一般指的是Linux中一个进程访问文件的唯一标识。
当我们在Linux中打开一个文件的时候,都会创建一个文件描述符。
每一个文件描述符的出现必然有一个对应的“文件”。
不同的文件描述符可能对应同一个文件。即文件描述符和文件的关系是n:1。
2. 出现的必要性
我们都知道在Linux系统中,一切皆文件,或者用一种更加准确的说法应该是一切皆文件描述符。不管是操作文件,目录,亦或是操作端口,在Linux系统中都体现为是操作文件描述符。这种的好处是:
- 基于文件描述符的IO操作符合POSIX标准
- 在Linux或Unix系统中,大量的系统调用都是基于文件描述符的
3. 创建FD的方法
- 进程直接open一个文件句柄,即会创建FD。在这种模式下FD:文件=1:1
- 从父进程继承一个文件句柄,会创建一个FD。这种情况的结果就是两个进程的两个FD指向同一个inode。当进程fork出一个子进程的时候,子进程会继承父进程所有的文件描述符的副本。在这种模式下FD:文件=n:1
4. FD的存储方式
系统会为每一个进程维护一个文件描述符表,所有的文件描述符都会在这个表里面创建一个索引
系统为了存储FD,用了三张表:
- 进程级的文件描述符表;
- 系统级的打开文件描述符表;
- 文件系统的i-node表。
三张表的关系如上图所示,
- 文件描述符表示进程级别的,即每一个进程都会有一张维护其占用FD的表。在进程内部,FD标识即第一列是唯一的。第二列是保存了指向系统级的打开文件描述符表的指针
- 打开文件描述符表是系统级别的,即整个系统只会保留一份。每一个进程在创建FD之后,都会在这个表里面注册一下。所有的进程FD都可以在这里找到一条对应的记录。分为三列,第一列是FD的状态,即可读,可写还是读写。第二列是当前FD操作的文件索引到哪里了。第三列是一个指向node的指针。
- i-node表是文件系统级别的。我们都知道,i-node是存储文件实际元数据的地方,即文件长度等属性。这里分几种情况说明:
当一个文件被打开一次时,那么其对应的node指针直接指向node位置
当一个文件在不同的进程中被打开两次时,那么在文件描述符表和打开文件描述符表都是存储两条记录,但是因为是同一个文件,所以是指向一个node记录的。如上图中打开文件描述符表的第2,3条记录
5. FD 名称(cwd,memory…\d[u|r|w])
- 当执行一个进程的时候,会有一个cwd的文件描述符。
cwd指的是current work directory,即当前工作目录。
为什么会有指定当前目录的FD呢?
是因为在Linux系统中,不管是目录还是文件都是以文件的方式存在的。所以当我们执行一个进程的时候,需要指定在哪个目录中执行,系统会去打开指定的执行目录,那么这个过程也就是一个打开系统文件的过程,即会创建FD。所以可以理解为任何一个进程都会有cwd的FD - 当执行一个进程的时候,会有一个txt的文件描述符。
txt可以理解为是程序代码,如应用程序的二进制库或者是共享库等。
为什么会有txt的FD呢?
既然是执行进程,那么必须有指定执行内容的代码文件。执行的时候需要读取文件内容,那么打开代码文件也必然会创建FD。所以可以理解为任何一个进程都会有txt的FD - 还有一些特殊的FD:
- rtd:根目录
- mem:内存映射文件
- mmap:内存映射设备
- 还有一些FD是数值开头的,这些表示的是这个进程执行时需要打开的一些文件描述符,这个数值也可以理解为是打开该文件时返回的一个整数。当初始化打开每一个进程的时候,都会默认有三个数值开头的FD,即0,1,2。也可以当做是内置FD,因为他们默认代表了特殊的含义
- 0:stdout,标准输出
- 1:stdin,标准输入
- 2:stder,错误输出
所以当应用程序内部打开文件的时候,数值都是从3开始的,有效范围是0-OPEN_MAX
在数值的后面还会加一个FD读写权限的标识:
- u:读写
- r:只读
- w:只写
6.FD TYPE
还有一个经常和FD一个使用的TYPE,即FD的type。
- REG :文件
- DIR:目录
- CHR :字符
- BLK:块设备
- UNIX:unix域套接字
- FIFO :先进先出队列
- IPv4:网际协议 (IP) 套接字
7. 查看FD使用情况
- 当想要查看某一个进程的FD的使用情况的时候,需要先找到查看进程的id,可以通过ps 查看,比如现在查看clickhouse-client的FD使用情况
- 可以看到进程id是77575
- 查看该进程的最大FD数量 cat /proc/77575/limits
找到这一行,可以看到可以支持的FD OPEN_MAX是1024,即最大可以支持1024个FD- 查看使用的FD ll /proc/77575/fd | wc -l
- 可以看到已经使用的是7个