文章目录
本作者从代码及源码的角度来总结探究文件描述符fd
参考:韦东山Linux嵌入式视频
文件描述符
Linux系统下一切皆文件。文件描述符fd是操作系统中用来唯一标识一个已打开文件的整数。本质上来说就是索引,即根据索引值寻找到对应的文件,可对其进行相应的操作。
使用open函数打开文件返回后得到一个文件描述符,使用read和write函数通过文件描述符fd进行读写操作。所有执行I/O操作的系统调用都通过文件描述符来实现。
首先,创建一个test.c文件
vim test.c
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <stdio.h>
#include <errno.h>
#include <string.h>
#include <unistd.h>
int main(int argc, char **argv)
{
if(argc != 2){
printf("Usage:%s <file>\n",argv[0]);
return -1;
}
int fd = open(argv[1], O_RDONLY);
printf("fd = %d\n",fd);
while(1){
sleep(100);
}
return 0;
}
编译,且运行打开test.c文件,&:表示后台运行,产生一个进程17985,打印文件描述符fd=3。
gcc -o test test.c
/test test.c &
ps查看后台进程资源运行情况
切换到proc虚拟文件系统查看进程信息,进入fd目录查看对应文件描述符fd=3指向的就是打开test.c
其中fd=0,1,2分别对应标准输入、标准输出、标准错误
内核源码:
路径:include\linux\sched.h 重要结构体:struct task_struct
- open函数的系统调用会进入内核调用内核函数,一个进程就会产生
struct task_struct
结构体。task_struct结构体用于管理进程,包含了一个进程所需的所有信息。这也是PCB(进程控制块) - task_struct结构体的成员变量含有
struct files_struct
结构体,files_struct结构体管理进程打开的所有文件的管理结构。 - files_struct结构体的成员变量含有
struct fdtable
结构体,fdtable结构体管理进程的文件描述符表。 - fdtable结构体的成员变量含有
struct file __rcu **fd
结构体,file结构体表示一个打开的文件,并且包含了许多与文件操作相关的信息和属性。
1、struct task_struct--->2、struct files_struct *files--->3、struct fdtable *fdt--->4、struct file **fd
特别的,
struct file __rcu **fd; /* current fd array */
fd是一个二级指针,指向的类型是是struct file
类型的指针,指向的地址存储的是strcut file*
类型的元素,地址里的元素strcut file*指向的是struct file
fd指向一个数组,数组元素为指针,指针类型为srtuct file *。
文件描述符本质上是一个指向文件表项的索引或引用
0 :STDIN_FILENO 接收键盘的输入
1 :STDOUT_FILENO 向屏幕输出
2 :STDERR_FILENO 标准错误
3:上图打开的test.c文件
而这些又分别指向自己的struct file结构体,而这个结构体存放着该文件的一些重要信息
关系如下所示
读取read文件的过程,转载