zoukankan      html  css  js  c++  java
  • 进程读写文件过程

    流程数据结构示意图


    • 初始情况我们先忽视task_struct2和task_struct3所附带的关系
    • 基本的流程是每一个进程的task_struct 中有一个对象 files_struct 专门存储files相关的信息,包括熟知的fd文件描述符等。我们调用系统调用返回的int类型的fd即指向的fd_array数组中存放的实际的 file 对象,这个对象相当于我们和实际的文件实体 inode 的一个消息传递者,也就是存在在多进程同时操作一个实际文件实体(task_struct和task_struct3)。

    基本数据结构简述


    • struct files_struct *files 进程中使用这个对象来管理所有的文件
    • struct fdtable fdtab 管理进程内的fd位图索引,能够指向到fd_array中实际的file结构
    • struct file *fd_array[NR_OPEN_DEFAULT]; 存储的进程所关联的所有file结构的数组对象
    • file对象存在引用,如果存在一个fd指向它,那么引用计数会增加,情况所属是fork一个子进程时fd都是指向同一个file
    • dentry对象是一个目录项,由操作系统维护,利用的是LRU的cache,file寻找一个inode需要经过它去寻找。存在引用,如果一个file指向它,那么引用计数会增加,所属情况是多进程同时打开同一个文件
    • inode对象是操作系统对磁盘上的文件系统进行缓存映射,对于具体的数据block缓存在address_space对象的缓存空间的,也就是内核的IO缓存区
    • 上述对象都有对应的特定的operator操作

    进程打开读写文件流程简述


    进程打开文件

    • 根据目录名称去调用dentry_cache是否存在对应的目录项,如果有需要对权限进行判断,如果没有则需要建立inode等对象生成新的dentry
    • 进程是否有对该inode的权限匹配
    • 创建新的file结构加入到task_struct的files中

    进程读写文件

    • 对于VFS是经过内核的缓冲区的(除了直接IO等操作,不经过内核的缓冲)
    • inode对象存放的address_space即它所对应的缓存区,缓冲区由一颗radix的树构成,单位是按页进行缓冲
    • 正常系统的读写文件是指,调用系统调用read()和write(),只经过内核一个缓冲区,如果调用C库那么存在用户空间还多了一个自带的缓存区。

    不带用户空间缓存的读写文件

    读文件

    • inode对象计算需要的页数
    • address_space的树中判断是否存在制定的页,否则找到磁盘制定页写入缓存
    • 将缓存复制拷贝到用户空间中

    写文件

    • inode对象计算需要的页数
    • address_space的树中判断是否存在制定的页,否则找到磁盘制定页写入缓存
    • 将用户空间的内容写入到缓存中
    • 落盘根据操作系统的脏页读写规则有关

    调用C库使得用户空间存在缓存的IO读写文件

    • 涉及的函数都带有f前缀,例如 fopen,fread,fwrite,fget,fput,fgets,fputs,fscanf,fprintf 等等
    • 目的降低内核空间和用户空间的切换,减少read和write函数的调用次数
    • 用户空间的缓存存在全缓存和行缓存,简单来说前者是缓存空间占满再调用系统调用,后者是按照行来标示调用系统调用

     

    子进程或者多进程调用的文件关系


    • 父进程fork操作使得子进程所带的struct_file对象内容一致,这意味着file对象都一致,共同使用偏移量等
    • 多进程共同打开同一个文件时,根据上述情况,它们公用的是inode对象但是各自的file对象不一致
    • 解决方式是例如使用O_APPEND类似标志或者是pwrite等使得lseek和write函数得到原子性操作,即获取当前偏移量以及写操作两者是一个事务

    mmap函数


    • 简单来说就是将IO实际内容映射到用户空间,不经过内核的缓冲区
    • 具体流程如下:
      • 进程启动映射过程,并在虚拟地址空间中为映射创建虚拟映射区域
      • 调用内核空间的系统调用函数mmap(不同于用户空间函数),实现文件物理地址和进程虚拟地址的一一映射关系
      • 进程发起对这片映射空间的访问,引发缺页异常,实现文件内容到物理内存(主存)的拷贝

    参考:

    linux系统编程之基础必备(三):文件描述符file descriptor与inode的相关知识

    从内核文件系统看文件读写过程

    进程打开及读写文件的过程

    inode and file descriptor table Interaction

    认真分析mmap:是什么 为什么 怎么用

  • 相关阅读:
    实现主从关系Form中汇总行金额/数量
    Custom.pll : 客制化菜单
    XML publisher 填充空白行数
    PLSQL提交带有模板的报表的方法
    使用Form个性化修改标准Form的LOV2
    在开发Form表单中的三种查询方法
    S3C2440 I2C实现
    NBOOT 基于VS2005的编程与编译(一)
    WINCE 6.0 调大image config.bib
    少用的defined,注意不是define
  • 原文地址:https://www.cnblogs.com/GrimReaper/p/9497349.html
Copyright © 2011-2022 走看看