• 进程如何维护打开的文件


    在进程的执行过程中会打开一系列文件,那么进程又是如何记录文件的状态呢?
     
    内核使用三种数据结构来表示一个记录项,弄清它们间的关系对于了解文件共享方面的知识很有帮助
    进程如何维护打开的文件

    1. 每个进程在进程表中都有一个记录项,记录项中包含有一张打开文件描述表,每个描述符占有一项。与每个文件描述符相关联的是:
       + 文件描述符标志
       + 指向一个文件表的指针
    2. 内核为所有打开文件维持一张文件表,每个文件表项包含:
       + 文件状态标志
       + 当前文件偏移量
       + 指向该文件V节点表项的指针
    3. 每个打开文件都有一个v节点结构(Linux中使用i节点),v节点包含了文件类型和对此文件进行各种操作的函数的指针。对于大多数文件,v节点还包含了该文件的i节点(i-node索引节点)。这个信息都是在打开文件的时候从磁盘上读入内存的,i节点包含了文件的所有者、文件长度、文件所在的设备、指向文件实际数据块在磁盘上所在位置的指针等。
     
    Linux没有使用v节点,而是使用了通用的节点结构,虽然两种实现有所不同,但在概念上v节点和i节点是一样的,两者都指向文件系统特有的i节点结构。
     
    当在两个进程中同时打开同一个文件时,每个进程表中都有一个记录项,都有自己的文件描述符和指向文件表的指针,而文件表中的v节点指针指向同一个v节点。
    进程如何维护打开的文件

    图中的两个进程分别在文件描述符3和4上打开同一文件,对于一个给定文件只有一个v节点表项,每个进程都有自己的文件表项的理由是:每个进程都拥有自己对该文件的当前偏移量。
     
    当使用dup函数或者fork之后,可能有多个文件描述符指向同一文件表项。在fork之后父子进程对于每一个打开文件描述符共享同一个文件表项。由于共享文件表项,因此拥有同一当前文件偏移量,以下实例:
     
    子进程共享所有父进程打开的文件,它们的文件描述符都指向同一个文件表项:
    进程如何维护打开的文件

    首先在文件描述符上打开指定文件,然后调用dup()函数,使得文件描述符4也指向对应文件,它们也共享文件表,因此具有相同的文件偏移量
    进程如何维护打开的文件

    下边用程序来验证上图中的情况
     
    #include <stdio.h>
    #include <fcntl.h>
    #include <unistd.h>
     
    int main()
    {
        FILE * fp1, * fp2;
        int fd1, fd2;
        if((fd1 = open("in", 2)) < 0)
        {
            printf("open error\n");
            exit(1);
        }
        lseek(fd1, 10, SEEK_SET);  
       
        fd2 = dup(fd1);            
        lseek(fd1, 20, SEEK_SET);  
        lseek(fd2, 30, SEEK_SET);  
        fp1 = fdopen(fd1, "r");    
        fp2 = fdopen(fd2, "r");
        printf("%d %d %d %d\n", fd1, fd2, ftell(fp1), ftell(fp2));
        return 0;
    }
    打印结果为:30 30,可见两个文件描述符对应的是同一个文件表,具有相同的文件偏移量
     
    复制一个描述符的另一种方法时fcntl函数,调用dup(filedes),等效于fcntl(filedes, F_DUPFD, 0);
    而调用dup2(filedes, filedes2);等效于close(fildes2); fcntl(filedes, F_DUPFD, filedes2);
  • 相关阅读:
    HAProxy从零开始到掌握
    学会这15点,让你分分钟拿下Redis数据库
    求一个字符串长度
    js时间戳怎么转成日期格式
    js获取url参数值的两种方式
    js 处理URL实用技巧
    jQuery操作radio、checkbox、select 集合
    js处理url的技巧和归纳
    ajax hash缓存
    jquery ajax跨域
  • 原文地址:https://www.cnblogs.com/qianye/p/2786362.html
Copyright © 2020-2023  润新知