文件描述符的本质
来源:互联网 发布:java poi 设置字体 编辑:程序博客网 时间:2024/05/18 01:20
1. 文件描述符的本质是数组元素的下标
右侧的表称为i节点表,在整个系统中只有1张。该表可以视为结构体数组,该数组的一个元素对应于一个物理文件。
中间的表称为文件表,在整个系统中只有1张。该表可以视为结构体数组,一个结构体中有很多字段,其中有3个字段比较重要:
- file status flags:用于记录文件被打开来读的,还是写的。其实记录的就是open调用中用户指定的第2个参数
- current file offset:用于记录文件的当前读写位置(指针)。正是由于此字段的存在,使得一个文件被打开并读取后,下一次读取将从上一次读取的字符后开始读取
- v-node ptr:该字段是指针,指向右侧表的一个元素,从而关联了物理文件。
左侧的表称为文件描述符表,每个进程有且仅有1张。该表可以视为指针数组,数组的元素指向文件表的一个元素。最重要的是:数组元素的下标就是大名鼎鼎的文件描述符。
open系统调用执行的操作:新建一个i节点表元素,让其对应打开的物理文件(如果对应于该物理文件的i节点元素已经建立,就不做任何操作);新建一个文件表的元素,根据open的第2个参数设置file status flags字段,将current file offset字段置0,将v-node ptr指向刚建立的i节点表元素;在文件描述符表中,寻找1个尚未使用的元素,在该元素中填入一个指针值,让其指向刚建立的文件表元素。最重要的是:将该元素的下标作为open的返回值返回。
这样一来,当调用read(write)时,根据传入的文件描述符,OS就可以找到对应的文件描述符表元素,进而找到文件表的元素,进而找到i节点表元素,从而完成对物理文件的读写。
2. fork 对文件描述符的影响
fork会导致子进程继承父进程打开的文件描述符,其本质是将父进程的整个文件描述符表复制一份,放到子进程的PCB中。因此父、子进程中相同文件描述符(文件描述符为整数)指向的是同一个文件表元素,这将导致父(子)进程读取文件后,子(父)进程将读取同一文件的后续内容。
案例分析(forkfd.c):
假设,./test.txt的内容是abcdefg。那么子进程的18行将读到字符ab;由于,父、子进程的文件描述符fd都指向同一个文件表元素,因此当父进程执行23行时,fd对应的文件的读写指针将移动到字符d,而不是字符b,从而24行读到的是字符def,而不是字符bcd。程序运行的最终结果是打印abdef,而不是abbcd。
相对应的,如果是两个进程独立调用open去打开同一个物理文件,就会有2个文件表元素被创建,并且他们都指向同一个i节点表元素。两个文件表元素都有自己独立的current file offset字段,这将导致2个进程独立的对同一个物理文件进行读写,因此第1个进程读取到文件的第1个字符后,第2个进程再去读取该文件时,仍然是读到的是文件的第1个字符,而不是第1个字符的后续字符。
对应用程序员而言,最重要结论是: 如果子进程不打算使用父进程打开的文件,那么应该在fork返回后立即调用close关闭该文件。
- 文件描述符的本质
- 尚未解决的问题----到底什么是文件描述符???其本质是什么???
- 矩阵的本质-运动的描述
- 转:矩阵的本质-运动的描述
- 矩阵的本质-运动的描述【好】
- 矩阵的本质-运动的描述
- 矩阵的本质-运动的描述
- 矩阵的本质-运动的描述
- 文件的本质
- 文件的本质--SHGetFileInfo()
- 文件的本质
- squid的文件描述符
- 文件描述符,文件句柄的区别
- 基于文件描述符的文件操作
- 探寻计算机文件的本质
- oracle参数文件的本质
- 目录与文件的本质
- json 最本质 最经典的描述~~~NB死了
- 进程与线程的区别
- C++编程基础笔记章节三
- http://liubin.org/promises-book/
- Android Studio 修改项目包名(Xposed)
- 一个简单的线程池(仿java的ScheduledFuture)
- 文件描述符的本质
- 事件分发之ViewGroup.dispatchTouchEvent(Android5.0)
- tomcat7-maven-plugin使用
- 用 Chrome 运行Android应用
- 《开发软件》Myeclipse.10.0+EditPlus+SQLserver2012
- 求两个数组的中位数,不合并数组
- 安装VBox共享文件增强功能VBoxGuestAdditions
- 深入浅出Java并发包—锁机制(二)
- 将本地程序推动到2