文件描述符(File Descriptors, 简称 FD)

发布时间:2026/6/10 3:46:25

文件描述符(File Descriptors, 简称 FD) 文章目录文件描述符file descriptor简称 fd本质上就是操作系统给“已打开资源”分配的一个编号。非负整数分配编号后后续操作就是围绕这个编号来的。代码通常不直接用 fd 编号真正直接使用 fd 编号的是底层系统调用和操作系统内核进程启动后默认会有3个文件描述符只有当代码需要操作系统帮你“打开某种外部资源”时才会分配fd,才会占用文件描述符。不是所有情况都是一个操作占一个fd每个进程都有自己的一张“文件描述符表”这张表里面记录fd 号码 - 这个 fd 指向什么资源。文件描述符不是全局唯一的而是进程内部的编号。为什么说fd是进程才有文件描述符是操作系统为了管理某个进程打开的资源而分配的编号子进程会继承父进程的一些 fd父子进程的 fd 表不是同一张表父进程和子进程都有自己的 fd 表线程有没有文件描述符线程属于同一个进程所以同一个进程内的多个线程共享同一张 fd 表。一切皆文件。Linux 把很多资源统一成“可以 open/read/write/close 的对象”。操作 fd就是操作 fd 指向的资源单进程允许打开的最大文件描述符数量的限制。cat /proc/PID/limits | grep open files硬限制本身也是进程的属性。进程启动时通常从父进程继承 soft limit 和 hard limit。ulimit -n 当前 shell 以及由这个 shell 启动的子进程默认会继承的 fd 限制如何修改soft limit看某个进程当前打开的fd总个数。ls /proc/PID/fd | wc -l查看进程具体打开了哪些资源 lsoflist open files -p PID。ls -l /proc/进程PID/fd进程当前打开的 fd 都指向哪些资源并找出重复最多的资源文件描述符file descriptor简称 fd本质上就是操作系统给“已打开资源”分配的一个编号。非负整数文件描述符File Descriptor简称 FD是操作系统为了高效管理已被打开的文件或资源而向应用程序返回的一个非负整数通常是从 0 开始的数字索引文件描述符就是进程访问文件、管道、终端、网络连接等资源时使用的“操作系统编号”文件描述符就是某个进程打开资源后操作系统给这个资源分配的编号。所以判断“是不是占用文件描述符”你就看这个进程有没有打开文件、管道、socket、终端、设备并且还没关闭有那就占用 fd。不是“文件自己占用文件描述符”而是某个进程打开了文件、管道、socket、终端之后操作系统给这个进程分配的一个编号这个编号就是文件描述符。可以把文件描述符理解成一个进程手里拿着的“资源号码牌”。不是“文件自己占用文件描述符”而是某个进程打开了文件、管道、socket、终端之后操作系统给这个进程发了一个编号这个编号就是文件描述符。分配编号后后续操作就是围绕这个编号来的。代码通常不直接用 fd 编号真正直接使用 fd 编号的是底层系统调用和操作系统内核进程启动后默认会有3个文件描述符进程默认有 fd0、fd1、fd2是为了让每个程序都有统一的输入、正常输出、错误输出通道。所以程序不需要知道自己是在终端里运行、被管道连接、被重定向到文件还是在 Docker/Celery 里运行它只需要读 fd0写 fd1报错写 fd2只有当代码需要操作系统帮你“打开某种外部资源”时才会分配fd,才会占用文件描述符。只要你打开了这些资源就通常会占 fd文件管道socket 网络连接终端设备文件不是所有情况都是一个操作占一个fd每个进程都有自己的一张“文件描述符表”这张表里面记录fd 号码 - 这个 fd 指向什么资源。文件描述符不是全局唯一的而是进程内部的编号。文件描述符是进程级别的资源编号。可以这样记每个进程有一张 fd 表fd 只是这张表里的编号不同进程可以有相同的 fd 编号线程共享所属进程的 fd 表fork / subprocess 创建子进程时子进程可能继承父进程的一些 fd。子进程 clangd 打开的文件不会算到父进程 里面Linux 里每个进程都有自己的 FD 表。比如PID 8 Celery worker childPID 79001 mcp-language-serverPID 79016 clangd它们各自有自己的/proc/8/fd/proc/79001/fd/proc/79016/fd所以你看到ls /proc/8/fd | wc -l1024说明是 Celery 子进程 PID 8 自己的 FD 满了。如果是 clangd 打开太多文件应该看ls /proc/79016/fd | wc -l而不是看 /proc/8/fd。为什么说fd是进程才有文件描述符是操作系统为了管理某个进程打开的资源而分配的编号子进程会继承父进程的一些 fd每个进程都有自己的 FD 表但子进程刚创建出来时系统会把父进程 FD 表里的部分条目“复制一份”给子进程所以不是“父子进程共用同一张 FD 表”而是父进程有自己的 FD 表子进程也有自己的 FD 表但是子进程刚出生时它的 FD 表内容很多是从父进程那里复制来的父子进程的 fd 表不是同一张表父进程和子进程都有自己的 fd 表子进程启动后也有自己的 fd0、fd1、fd2。默认情况下它们连接到和父进程一样的终端只有你显式写了 PIPE、重定向文件等才会把它们改接到别的地方线程有没有文件描述符线程属于同一个进程所以同一个进程内的多个线程共享同一张 fd 表。一切皆文件。Linux 把很多资源统一成“可以 open/read/write/close 的对象”。在 Linux 和 Unix操作系统中有一个非常核心的哲学叫做“一切皆文件”。这意味着不仅普通的文本文件是文件网络连接Socket、管道Pipe、标准输入输出、甚至硬件设备在系统底层都被抽象成了“文件”。而FD 就是访问这些资源的“钥匙”。/dev/null 理解成Linux 提供的一个“特殊文件入口”你往里面写东西系统直接丢掉。它不是普通的 .txt 文件不会真的保存 hello。操作 fd就是操作 fd 指向的资源fd 就是进程访问资源的编号操作 fd就是让操作系统根据这个编号找到背后的文件、终端、管道、socket 等资源然后对它执行读、写、关闭等操作单进程允许打开的最大文件描述符数量的限制。cat /proc/PID/limits | grep “open files”“单进程允许打开的最大文件描述符数量限制”就是一个进程最多能同时打开多少个文件、管道、socket、设备等资源硬限制本身也是进程的属性。进程启动时通常从父进程继承 soft limit 和 hard limit。ulimit -n 当前 shell 以及由这个 shell 启动的子进程默认会继承的 fd 限制如何修改soft limit看某个进程当前打开的fd总个数。ls /proc//fd | wc -l先列出这个进程所有 fd再统计有多少行得到这个进程当前打开了多少个 fd查看进程具体打开了哪些资源 lsoflist open files -p 。ls -l /proc/进程PID/fdfd 表示这个进程打开了某个资源后面的字母表示这个 fd 对这个资源的访问方式。即这个资源是以什么方式被打开的读、写、读写。进程当前打开的 fd 都指向哪些资源并找出重复最多的资源遍历 PID513811 进程的所有 fd,查看每个 fd 指向哪里,把相同目标归类统计,按数量从多到少排序,显示前 50 个forfdin/proc/513811/fd/*;doreadlink$fd;done|sort|uniq-c|sort-nr|head-50

相关新闻