个人建设视频网站制作,设备建设网站,电子商务网站开发课程设计,团总支网站建设宣传感谢你的阅读#xff0c;是对我最大的鼓励#xff01;#xff01;#xff01;#xff01; 目录 fd理解
文件操作重定向
让我们回顾C语言文件操作
首选我们要知道2个知识点#xff1a;
额外知识点
如何理解一切皆文件呢#xff1f;
当父进程fork创建子进程是否创建…感谢你的阅读是对我最大的鼓励 目录 fd理解
文件操作重定向
让我们回顾C语言文件操作
首选我们要知道2个知识点
额外知识点
如何理解一切皆文件呢
当父进程fork创建子进程是否创建文件。 fd理解
在操作系统内核中进程PCB还管理着一个结构体files_struct。这个结构体管理着该进程打开的文件一般情况下进程文件1n的比例既然如此我们就需要将这多个文件管理起来。
文件加载到内存中会形成一个叫做file的结构体。 同样的一个进程可以打开多个文件这些打开的文件以某种数据结构关联在一起。 而我们的进程中有个叫做files_struct 的结构体他的里面有一个文件指针数组成员变量每一个元素保存的都是对应文件的地址。
而我们的fd其实就是files_struct中数组下标数字。 文件操作就是拿着fd数组下标经过PCB中files_struct指针找到files_struct结构体然后根据就是根据fd下标索引到数组中找到相应操作的文件地址然后通过文件地址找到需要操作的file结构体。 文件操作重定向
让我们回顾C语言文件操作
//......
FILE*fpfopen(./test.txt,w);
//......
fclose(fp);看似平平无奇的一句话现在来看我们理解FILE*是指针但是什么是FILE吗为什么fp就可以操作文件了呢提前close会怎么样呢
记住所有的语言其实都是在操作系统系统语言上的接口所以fopen、fclose其实只是在系统接口open、close上的封装。而FILE是一个结构体那么理解fd的话我们就立刻知道FILE这个结构体中一定要包含一份数字这个数字一定是为了在files_struct结构体的数组中寻找相关的文件下标。
FILE是C语言文件操作所需要的结构体该结构体中一定有一份数字为了操作在底层files_struct结构体中指针数组成员寻找相应的file结构体。
那么重定向是什么意思呢
比如以下字符串
//C
FILE*fpfopen(./test.txt,w);
printf(holle world\n);
该字符串原本经过printf函数要打印在显示屏上经过了流重定向打印到了test.txt文件中。
这是个什么原理呢
首选我们要知道2个知识点
1、程序会默认打开标准输入、标准输出、标准错误的三个流、对应在C语言的就是stdin stdout stderr这仨其实就是FILE*指针。
2、files_struct中的数组会顺序存储打开的文件意思就是原本fd0标准输入、1标准输..出、2标准错误、3文件1、4文件2...如果前一个文件关闭会清空files_struct 数组的数据但是数组不会数据前移再打开一个文件就会加载到该位置。 让我们来画图理解重定向的原理
下面是我们files_struct结构体中数组与file结构体的链接。 现在我们关闭file2标准输出将关闭键盘输入操作。没有打开新文件我们就会使下标1的内存就会被置空不连接任何文件。 这个时候将一个文件载入到进程在文件file结构体之间也会有着链接关系新打开的文件会增到这个数据结构中。 操作系统会让打开文件的进程的内核数据结构files_struct的数组存储打开的文件存储在内存的地址而我们存储的方式是按顺序低到高寻找是否有未被使用的低下标元素这时候发现1下标空间未被使用这时候就会存储该文件的地址完成进程与打开文件的联系。 操作验证关闭标准输出然后打开文件然后向stdout流写入文件) 关闭fd1标准输出使用3个函数向标准输出打印字符串。
--------
首先查看log.txt无任何字符串 ---------
运行程序没有在屏幕打印数据 --------- 字符串流向了log.txt中
这就是我们所谓的重定向。是不是很简单简单个p 额外知识点
如何理解一切皆文件呢
其实这个概念是在打开的文件构成一个数据结构层面的概念。 我们的一切皆文件就是站在vfs层理解这句话的为什么呢由于每个硬件的读写操作都是不一样的但是我们都要同一的管理起来这个时候就见他们的操作方式的地址加载到file结构体中每个结构体都有着不同硬件软件文件的读写方式我们在vfs一视同仁的认为他们都在vfs层都是叫做文件。这就是我们一切皆文件的概念。 当父进程fork创建子进程是否创建文件。
不会的。子进程会有着独立的进程空间files_struct是父进程继承但是文件是多个进程共享的不会因为子进程的创建而复制一份文件。 有一点子进程会继承父进程打开的文件地址所以子进程也可以访问到和父进程相同的文件。如果父进程重定向了标准输入标准输出等等映射关系我们的子进程也会重定向。
因为子进程是父进程的拷贝这属于一种深拷贝中的浅拷贝可以浏览我另一篇文章vector【实现】迭代器失效以及非法的间接寻址、深拷贝中的浅拷贝。_云的小站的博客-CSDN博客 感谢你的阅读是对我最大的鼓励 fd的本质是内核当中进程和打开文件对应关系的数组的下标 如何理解一切皆文件呢文件在系统层面有一个vfs的虚拟文件系统当中会包含每一个被打开文件的结构体struct file 这个结构体有一批函数指针这批函数指针直接帮我们指向底层方法。所以在上层我们可以以同一的视角struct file的方式看待所有文件 所以一切皆文件是在vfs层的看待文件而不是在硬件看待。
linux task_struct-files_struct-vfs层file(struct结构体)-驱动层 echo ”holle world“ log.txt 就是echo的的fd1 关闭然后再打开log.txt文件完成了输出重定向
fd 当fork创建子进程时候进程数据会拷贝但是文件数据不拷贝所以子父进程的files_struct 都是指向相同的file结构体 如果父进程曾经改变了
file结构体中有一个 int cnt 引用计数 当有一个进程指向该文件cnt 一个进程close该文件cnt-- 当cnt0 文件退出内存释放空间