文章目录

  • 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系统中都体现为是操作文件描述符。这种的好处是:

  1. 基于文件描述符的IO操作符合POSIX标准
  2. 在Linux或Unix系统中,大量的系统调用都是基于文件描述符的

3. 创建FD的方法

  1. 进程直接open一个文件句柄,即会创建FD。在这种模式下FD:文件=1:1
  2. 从父进程继承一个文件句柄,会创建一个FD。这种情况的结果就是两个进程的两个FD指向同一个inode。当进程fork出一个子进程的时候,子进程会继承父进程所有的文件描述符的副本。在这种模式下FD:文件=n:1

4. FD的存储方式

系统会为每一个进程维护一个文件描述符表,所有的文件描述符都会在这个表里面创建一个索引
系统为了存储FD,用了三张表:

  1. 进程级的文件描述符表;
  2. 系统级的打开文件描述符表;
  3. 文件系统的i-node表。

centos 文件描述符fd 查看命令 linux中文件描述符_tcp/ip

三张表的关系如上图所示,

  1. 文件描述符表示进程级别的,即每一个进程都会有一张维护其占用FD的表。在进程内部,FD标识即第一列是唯一的。第二列是保存了指向系统级的打开文件描述符表的指针
  2. 打开文件描述符表是系统级别的,即整个系统只会保留一份。每一个进程在创建FD之后,都会在这个表里面注册一下。所有的进程FD都可以在这里找到一条对应的记录。分为三列,第一列是FD的状态,即可读,可写还是读写。第二列是当前FD操作的文件索引到哪里了。第三列是一个指向node的指针。
  3. i-node表是文件系统级别的。我们都知道,i-node是存储文件实际元数据的地方,即文件长度等属性。这里分几种情况说明:
     当一个文件被打开一次时,那么其对应的node指针直接指向node位置
     当一个文件在不同的进程中被打开两次时,那么在文件描述符表和打开文件描述符表都是存储两条记录,但是因为是同一个文件,所以是指向一个node记录的。如上图中打开文件描述符表的第2,3条记录

5. FD 名称(cwd,memory…\d[u|r|w])

  1. 当执行一个进程的时候,会有一个cwd的文件描述符。
    cwd指的是current work directory,即当前工作目录。
    为什么会有指定当前目录的FD呢?
    是因为在Linux系统中,不管是目录还是文件都是以文件的方式存在的。所以当我们执行一个进程的时候,需要指定在哪个目录中执行,系统会去打开指定的执行目录,那么这个过程也就是一个打开系统文件的过程,即会创建FD。所以可以理解为任何一个进程都会有cwd的FD
  2. centos 文件描述符fd 查看命令 linux中文件描述符_文件描述符_02

  3. 当执行一个进程的时候,会有一个txt的文件描述符。
    txt可以理解为是程序代码,如应用程序的二进制库或者是共享库等。
    为什么会有txt的FD呢?
    既然是执行进程,那么必须有指定执行内容的代码文件。执行的时候需要读取文件内容,那么打开代码文件也必然会创建FD。所以可以理解为任何一个进程都会有txt的FD
  4. centos 文件描述符fd 查看命令 linux中文件描述符_linux_03

  5. 还有一些特殊的FD:
  1. rtd:根目录
  2. mem:内存映射文件
  3. mmap:内存映射设备

centos 文件描述符fd 查看命令 linux中文件描述符_运维_04

  1. 还有一些FD是数值开头的,这些表示的是这个进程执行时需要打开的一些文件描述符,这个数值也可以理解为是打开该文件时返回的一个整数。当初始化打开每一个进程的时候,都会默认有三个数值开头的FD,即0,1,2。也可以当做是内置FD,因为他们默认代表了特殊的含义
  1. 0:stdout,标准输出
  2. 1:stdin,标准输入
  3. 2:stder,错误输出

所以当应用程序内部打开文件的时候,数值都是从3开始的,有效范围是0-OPEN_MAX
在数值的后面还会加一个FD读写权限的标识:

  1. u:读写
  2. r:只读
  3. w:只写

centos 文件描述符fd 查看命令 linux中文件描述符_运维_05

6.FD TYPE

还有一个经常和FD一个使用的TYPE,即FD的type。

  1. REG :文件
  2. DIR:目录
  3. CHR :字符
  4. BLK:块设备
  5. UNIX:unix域套接字
  6. FIFO :先进先出队列
  7. IPv4:网际协议 (IP) 套接字

7. 查看FD使用情况

  1. 当想要查看某一个进程的FD的使用情况的时候,需要先找到查看进程的id,可以通过ps 查看,比如现在查看clickhouse-client的FD使用情况

centos 文件描述符fd 查看命令 linux中文件描述符_linux_06

  1. 可以看到进程id是77575
  2. 查看该进程的最大FD数量 cat /proc/77575/limits

centos 文件描述符fd 查看命令 linux中文件描述符_文件描述符_07


  1. 找到这一行,可以看到可以支持的FD OPEN_MAX是1024,即最大可以支持1024个FD
  2. 查看使用的FD ll /proc/77575/fd | wc -l

centos 文件描述符fd 查看命令 linux中文件描述符_文件描述符_08

  1. 可以看到已经使用的是7个