文件描述符
文件描述符(fd)是进程用于引用已打开 I/O 对象的非负整数。Linux 中普通文件、socket、管道等都可以通过描述符操作;编号本身不包含文件路径或网络地址。
1. 面试核心
先记住这几条,再读正文- fd 是进程描述符表的索引,不是磁盘文件本身。
- dup 或 fork 后的描述符可能引用同一个打开文件描述,共享文件偏移等状态。
- close 释放当前引用,编号之后可被复用。
2. 描述符表与打开文件描述
进程 fd 3 ─┐
├→ 打开文件描述 → 文件对象
进程 fd 4 ─┘
调用 open 通常创建新的打开文件描述,再返回一个 fd。dup 复制描述符引用,因此经两个 fd 读取同一普通文件时可能共享偏移。两次独立 open 同一路径通常获得独立偏移。
文件状态标志与文件偏移存放在打开文件描述层;是否在 exec 时关闭的 FD_CLOEXEC 是描述符层属性。这两层不能混淆。
3. 生命周期与泄漏
每次成功打开都需要明确谁负责关闭。异常、提前返回和连接失败后的清理分支同样需要释放资源。长时间运行的服务即使每次只漏一个 fd,也可能耗尽进程限制。
删除一个已经打开的文件路径,不代表它的数据立刻从磁盘释放:只要仍有打开引用或其他硬链接,存储可能继续存在。这能解释“文件已经删掉,磁盘空间却没有回来”的部分情况。
4. 使用边界
异步任务仅记住 fd 数字时,要防止关闭后编号复用:原先 3 表示连接 A,稍后可能已经表示连接 B。对象生命周期、取消与事件处理需要协调。
检查 Linux 服务描述符可查看 /proc/PID/fd 和资源限制,再区分文件、socket、管道的增长。读取 EOF、暂时没有数据以及发生错误是不同结果,不能统一当作连接可关闭。
5 · 面试题卡片
先想答案,再翻面题目来自公开面经。点任意一张进入翻卡,可左右切换,看完回到这里。
逐张翻看 1 张 →5.1 为什么两个文件描述符可能共享读取位置,关闭一个后另一个还能使用?
出现公司:暂无已核验的公开来源(本站自测)
考察重点:描述符与打开文件描述的区别、共享偏移和引用生命周期。
相关内容:面试核心、描述符表与打开文件描述、使用边界。
参考回答
dup 得到的新 fd 与旧 fd 引用同一个打开文件描述,所以共享偏移。close 只释放指定描述符的引用,只要还有其他有效引用,底层对象通常继续存在。两次独立 open 同一路径不等于 dup,通常不会共享同一个文件偏移。