浙江省住房和城乡建设厅网官方网站,wordpress ajax评论,自己怎样做网站平台,食药监局网站建设方案Linux 文件描述符
Linux 中一切皆文件#xff0c;比如 C 源文件、视频文件、Shell脚本、可执行文件等#xff0c;就连键盘、显示器、鼠标等硬件设备也都是文件。
一个 Linux 进程可以打开成百上千个文件#xff0c;为了表示和区分已经打开的文件#xff0c;Linux 会给每个…Linux 文件描述符
Linux 中一切皆文件比如 C 源文件、视频文件、Shell脚本、可执行文件等就连键盘、显示器、鼠标等硬件设备也都是文件。
一个 Linux 进程可以打开成百上千个文件为了表示和区分已经打开的文件Linux 会给每个文件分配一个编号一个 ID这个编号就是一个整数被称为文件描述符File Descriptor。
文件描述符FD: File Descriptor
在 Linux 操作系统中当一个应用程序或进程操作系统资源时首先会触发文件调用事件通过应用程序或进程发送一个调用文件的信号给操作系统内核内核会在 打开文件表 中增加一条记录同时将打开文件表中新增的记录返回给应用程序或进程而应用程序或进程接收到来自内核返回的信息称为 文件描述符(file desrciption)。
当我们打开文件时操作系统在内存中要**创建相应的数据结构来描述目标文件file struct表示一个已经打开的文件对象**。而进程执行open系统调用必须让进程和文件关联起来。每个进程都有一个指针 *files 保存在进程控制块PCB中 , 它指向一张表 files_struct。
files_struct表包含一个指针数组每个元素都是一个指向打开文件的指针。本质上文件描述符就是该数组的下标。所以只要获取到文件描述符就可以找到对应的文件。 文件描述符是一个简单的非负整数用来表明每一个被进程锁打开的文件实际上通过 内核 返回的文件描述符正是 打开文件表 中该文件的索引记录是一个非负整数。文件描述符 通常从 3 开始记录。
在Linux操作系统上每个进程都有三个标准的 「POSIX」文件描述符对应三个标准流按照索引以 0 开始分别是 Standard Input(标准输入)、Standard Output(标准输出)、Standard Error(标准错误)。
文件调用流程
一个 Linux 进程启动后会在内核空间中创建一个 PCB 控制块PCB 内部有一个文件描述符表File descriptor table记录着当前进程所有可用的文件描述符也即当前进程所有打开的文件。
除了文件描述符表系统还需要维护另外两张表
打开文件表Open file tablei-node 表i-node table
文件描述符表每个进程都有一个打开文件表和 i-node 表整个系统只有一个它们三者之间的关系如下图所示 通过文件描述符可以找到文件指针从而进入打开文件表。该表存储了以下信息
文件偏移量也就是文件内部指针偏移量。调用 read() 或者 write() 函数时文件偏移量会自动更新当然也可以使用 lseek() 直接修改。状态标志比如只读模式、读写模式、追加模式、覆盖模式等。i-node 表指针。
然而要想真正读写文件还得通过打开文件表的 i-node 指针进入 i-node 表该表包含了诸如以下的信息
文件类型例如常规文件、套接字或 FIFO。文件大小。时间戳比如创建时间、更新时间。文件锁。
对上图的进一步说明
在进程 A 中文件描述符 1 和 20 都指向了同一个打开文件表项标号为 23指向了打开文件表中下标为 23 的数组元素这可能是通过调用 dup()、dup2()、fcntl() 或者对同一个文件多次调用了 open() 函数形成的。进程 A 的文件描述符 2 和进程 B 的文件描述符 2 都指向了同一个文件这可能是在调用 fork() 后出现的即进程 A、B 是父子进程关系或者是不同的进程独自去调用 open() 函数打开了同一个文件此时进程内部的描述符正好分配到与其他进程打开该文件的描述符一样。进程 A 的描述符 0 和进程 B 的描述符 3 分别指向不同的打开文件表项但这些表项均指向 i-node 表的同一个条目标号为 1976换言之它们指向了同一个文件。发生这种情况是因为每个进程各自对同一个文件发起了 open() 调用。同一个进程两次打开同一个文件也会发生类似情况。
有了以上对文件描述符的认知我们很容易理解以下情形
同一个进程的不同文件描述符可以指向同一个文件不同进程可以拥有相同的文件描述符不同进程的同一个文件描述符可以指向不同的文件一般也是这样除了 0、1、2 这三个特殊的文件不同进程的不同文件描述符也可以指向同一个文件。
参考文献
[1]: Linux文件描述符到底是什么
[2]: 什么是文件描述符
[3]: 文件描述符