美文网首页
文件描述符的本质

文件描述符的本质

作者: 我是强强 | 来源:发表于2017-12-24 23:22 被阅读0次

文件描述符的本质

文件描述符本质

2161

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):

[c]view plaincopy

#include 

#include 

#include 

#include 

#include 

#include 

intmain(void)

{

intfd, pid, status;

charbuf[10];

if((fd = open("./test.txt", O_RDONLY)) < 0) {

perror("open");  exit(-1);

}

if((pid = fork()) < 0) {

perror("fork");  exit(-1);

}elseif(pid == 0) {//child

read(fd, buf, 2);

write(STDOUT_FILENO, buf, 2);

}else{//parent

sleep(2);

lseek(fd, SEEK_CUR, 1);

read(fd, buf, 3);

write(STDOUT_FILENO, buf, 3);

write(STDOUT_FILENO,"\n", 1);

}

return0;

}

假设,./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关闭该文件。

相关文章

  • 文件描述符的本质

    文件描述符的本质 文件描述符本质 2161 1. 文件描述符的本质是数组元素的下标 右侧的表称为i节点表,在整个系...

  • IO多路复用的三种机制:select 、poll 、epoll

    IO多路复用本质 检测多个文件描述符是否有变化 。让单个进程可以监视多个文件描述符,一旦某个描述符就绪(一般是读就...

  • 第三章 文件I/O

    文件描述符 所有打开的文件都通过文件描述符引用。操作(读写)该文件描述符就相当于操作该文件。文件描述符是一个非负的...

  • 第三章 文件IO

    对于内核而言,所有打开的文件都通过文件描述符引用,文件描述符是一个非负整数文件描述符标准符号常量文件描述符0标准输...

  • ios进阶路线 shell脚本语言基础教程(四)

    上篇我们讲了文件描述符还有自定义文件描述符,补充一下如何关闭自定义的文件描述符 语法:exec 描述符>&- 案例...

  • 文件I/O和记录锁

    文件描述符: 文件描述符是一个非负整数,所有打开的文件都通过文件描述符引用。按照惯例:0(STDIN_FILENO...

  • Linux中文件描述符,重定向与标准输入输出

    Linux中文件描述符,重定向与标准输入输出 文件描述符:内核(kernel)利用文件描述符(file descr...

  • 认识安卓的文件描述符FileDescriptor

    理解文件描述符 文件描述符(FileDescriptor) 这是Unix/Linux系统文件操作的相关概念,And...

  • Shell--呈现数据

    文件描述符 用stdout和stderr文件描述符来在多个位置生成输出,重定向相应的文件描述符 临时重定向 在脚本...

  • ulimit ps dmesg which stat 命令小结

    ulimit 设置查看文件描述符命令 ulimit -n查看文件描述符 ulimit -SHn 65535设置文件...

网友评论

      本文标题:文件描述符的本质

      本文链接:https://www.haomeiwen.com/subject/ildkgxtx.html