Linux 文件相关底层知识

1. PCB(task_struct,进程控制块)

操作系统每创建一个程序(进程),就要在内存里开辟一块空间记录这个进程的全部信息,这块信息就叫 PCB。 里面存着:进程 ID、进程状态、内存信息、打开了哪些文件等等一大堆东西。

其中有一个成员,是专门管文件的:files,它指向文件描述符表。

简单理解: PCB = 这个进程的「个人档案袋」,档案袋里面有一张清单,就是文件描述符表。

2. 文件描述符表

它本质是一个数组,属于这个进程私有,别的进程看不到这个表。 数组的每一条记录包含两样东西:

  1. 下标:文件描述符 fd,就是一个普通整数(0、1、2、3、4......)
  2. 数组的值:一个指针,指向内核里的 struct file 对象。

举例子 默认启动进程,自动打开 3 个文件: fd=0 标准输入(键盘) fd=1 标准输出(屏幕打印) fd=2 标准错误(报错信息)

重点: fd 只是数组的编号,本身不是文件,只是一个快捷号码。 不同进程可以都用 fd=3,互相之间完全不冲突,因为每个进程有自己独立的这张表。

3. struct file(文件打开实例)

当你调用open()打开一个文件,内核就会在内存新建一个 struct file。

关键点:每 open 一次,就新建一个 struct file。

它记录的是「这次打开文件之后的状态」,里面重要信息:

  • f_pos:当前读到文件的哪个位置(读写偏移量)
  • f_flags:你是以只读、只写还是追加方式打开的
  • f_inode:指针,指向这个文件对应的 inode
  • f_op:文件操作函数(read、write、close 等)
  • f_count:引用计数,记录现在有多少个 fd 在引用这个 struct file

生活化理解: inode 是一本书本身; struct file 就是你翻开这本书看书,会记住你读到第几页(f_pos)。 你两次打开同一本书,相当于翻开两份独立的阅读记录,各自读到的页码互不影响。

重要场景: fork 创建子进程的时候,子进程会复制父进程的文件描述符表。父子进程 fd 指向同一个 struct file。 此时大家共用同一个 f_pos,你写一点,另一个读的时候就从新位置读。管道进程通信就是靠这个特性实现的。

close (fd) 做的事情:把 struct file 的引用计数减 1。当计数变成 0,内核就释放这个 struct file。

4. struct inode(文件本体)

inode 代表文件本身,存在内核内存里(从磁盘加载上来)。 磁盘上的一个文件,永远只对应一个 inode,不管多少个进程打开它。

inode 保存文件的固定属性,不会记录读到哪里:

  • 文件大小、权限、所属用户
  • 文件数据在磁盘上存放在哪些块
  • 文件类型(普通文件、目录、管道、socket、设备文件)

一句话区分: inode:文件本身的静态信息(不变) struct file:一次打开文件产生的动态阅读记录(会变,比如读文件会改变 f_pos)

整体串联一遍流程

  1. 创建进程,内核分配 PCB(进程档案)
  2. PCB 里面有指针,指向属于这个进程的文件描述符表(数组)
  3. 调用 open 打开文件:内核找到磁盘上文件,加载它的 inode 到内存
  4. 内核新建 struct file,让它的 f_inode 指向这个 inode
  5. 在当前进程的 fd 表里找一个空闲下标,填入指向这个 struct file 的指针,返回这个下标给用户,就是 fd
  6. 之后你调用 read (fd): 根据 fd 去 fd 表拿到 struct file → 借助 struct file 里的 inode 找到磁盘数据,同时更新 struct file 里面的读写位置 f_pos

进程间通信(管道)怎么利用这套结构

管道本质不是磁盘上的文件,是内核内存里的特殊 inode。

  1. pipe 系统调用,内核创建管道,生成特殊 inode,创建 struct file
  2. 得到两个 fd(读端 fd、写端 fd),在当前进程 fd 表中,两个 fd 指向同一个 struct file
  3. fork 之后,子进程复制 fd 表,父子进程都持有这两个 fd
  4. 父子进程共用同一个 struct file,共享缓冲区和读写偏移,一个写,另一个就可以读到数据
相关推荐
骑着蜗牛撵大象3271 小时前
让 Codex 值夜班:把告警排查与巡检接成可回滚的自动化链路
android·java·运维·ai·自动化·codex·智能体
天远数科1 小时前
零信任架构实战:基于天远企业年报信息核验构建自动化供应商准入资质合规审查网关
运维·人工智能·架构·自动化
TangGeeA1 小时前
Control CLI Tutorial:用 aio 从终端控制 aiopsterm
运维·人工智能
VIP_CQCRE1 小时前
上线 AI 分站别一次改完:一套可回滚的配置与验收流程
运维·产品设计·ai工具·技术教程·acedatacloud
靳某某。2 小时前
Ubuntu安装php8.4 及redis ngin
linux·redis·ubuntu
Shell运维手记2 小时前
Shell 结构化命令知识点总结(case、for、while)
运维·microsoft·shell·脚本
一只旭宝2 小时前
回调函数(Callback)
linux·服务器·算法
less_121382 小时前
鸿蒙 WPS Open SDK 二开复盘:从注册、打开到回传的完整能力链
服务器·sdk·harmonyos·wps·鸿蒙开发
木泽八2 小时前
《Ubuntu系统GRUB引导修复操作记录》
linux·运维·ubuntu
水饺编程3 小时前
第2章:Linux 基础,删除用户
linux·c语言·汇编