结论:文件描述符(fd)是进程打开文件表中条目的整数索引,内核通过它找到对应的打开文件对象(file 结构,记录偏移量、模式、指向 inode)。"一切皆文件"指普通文件、目录、管道、socket、设备都用同一套 open/read/write/close 接口操作——fd 是统一的句柄抽象。
展开:三层结构要分清:1)进程级——每个进程的 fd 表(files_struct),fd 只是数组下标,0/1/2 预留给标准输入/输出/错误;2)系统级——打开文件表(struct file),同一文件被打开多次产生多个条目,记录各自的读写偏移;fork 后父子共享条目(共享偏移),dup 同理,各自 open 则偏移独立;3)文件系统级——inode 代表文件本身(元数据、数据块位置),硬链接让多个名字指向同一 inode。统一抽象的红利:管道、重定向、epoll 对所有 fd 一视同仁,工具链(cat < file、cmd | less)无需关心源是磁盘还是网络。易错点:fd 数量有限(ulimit -n,高并发服务要调大);fd 泄漏的表现是 "Too many open files",用 ls /proc/<pid>/fd 排查;close 的是 fd 表项,内核对象在最后一个引用关闭时才释放。
追问方向:/proc/self/fd 的实现原理、SCM_RIGHTS 如何通过 Unix socket 传递 fd。