在Linux中,进程是通过文件描述符(file descriptors,简称fd)而不是文件名来访问文件的,文件描述符实际上是一个整数。Linux中规定每个进程能最多能同时使用NR_OPEN个文件描述符,这个值在fs.h中定义,为1024*1024(2.0版中仅定义为256)。

每个文件都有一个32位的数字来表示下一个读写的字节位置,这个数字叫做文件位置。每次打开一个文件,除非明确要求,否则文件位置都被置为0,即文件的开始处,此后的读或写操作都将从文件的开始处执行,但你可以通过执行系统调用LSEEK(随机存储)对这个文件位置进行修改。Linux中专门用了一个数据结构file来保存打开文件的文件位置,这个结构称为打开的文件描述(open file description)。这个数据结构的设置是煞费苦心的,因为它与进程的联系非常紧密,可以说这是VFS中一个比较难于理解的数据结构。

file结构中主要保存了文件位置,此外,还把指向该文件索引节点的指针也放在其中。file结构形成一个双链表,称为系统打开文件表,其最大长度是NR_FILE,在fs.h中定义为8192。

file结构在include\linux\fs.h中定义如下:

  1. struct file
  2. {
  3. struct list_head        f_list;    /*所有打开的文件形成一个链表*/
  4. struct dentry           *f_dentry; /*指向相关目录项的指针*/
  5. struct vfsmount         *f_vfsmnt; /*指向VFS安装点的指针*/
  6. struct file_operations  *f_op;     /*指向文件操作表的指针*/
  7. mode_t f_mode;                                  /*文件的打开模式*/
  8. loff_t f_pos;                                   /*文件的当前位置*/
  9. unsigned short f_flags;                         /*打开文件时所指定的标志*/
  10. unsigned short f_count;                           /*使用该结构的进程数*/
  11. unsigned long f_reada, f_ramax, f_raend, f_ralen, f_rawin;
  12. /*预读标志、要预读的最多页面数、上次预读后的文件指针、预读的字节数以及预读的页面数*/
  13. int f_owner;                  /* 通过信号进行异步I/O数据的传送*/
  14. unsigned int         f_uid, f_gid;  /*用户的UID和GID*/
  15. int                 f_error;       /*网络写操作的错误码*/
  16. unsigned long f_version;           /*版本号*/
  17. void *private_data;                      /* tty驱动程序所需 */
  18. };

内核中,对应于每个进程都有一个文件描述符表,表示这个进程打开的所有文件。文件描述表中每一项都是一个指针,指向一个用于描述打开的文件的数据块———file对象,file对象中描述了文件的打开模式,读写位置等重要信息,当进程打开一个文件时,内核就会创建一个新的file对象。需要注意的是,file对象不是专属于某个进程的,不同进程的文件描述符表中的指针可以指向相同的file对象,从而共享这个打开的文件。file对象有引用计数,记录了引用这个对象的文件描述符个数,只有当引用计数为0时,内核才销毁file对象,因此某个进程关闭文件,不影响与之共享同一个file对象的进程.

file对象中包含一个指针,指向dentry对象。dentry对象代表一个独立的文件路径,如果一个文件路径被打开多次,那么会建立多个file对象,但它们都指向同一个dentry对象。
 
dentry对象中又包含一个指向inode对象的指针。inode对象代表一个独立文件。因为存在硬链接与符号链接,因此不同的dentry对象可以指向相同的inode对象.inode 对象包含了最终对文件进行操作所需的所有信息,如文件系统类型、文件的操作方法、文件的权限、访问日期等。
 
打开文件后,进程得到的文件描述符实质上就是文件描述符表的下标,内核根据这个下标值去访问相应的文件对象,从而实现对文件的操作。
注意,同一个进程多次打开同一个文件时,内核会创建多个file对象。
当进程使用fork系统调用创建一个子进程后,子进程将继承父进程的文件描述符表,因此在父进程中打开的文件可以在子进程中用同一个描述符访问。
 
 
 
链接:
 
http://oss.org.cn/kernel-book/ch08/8.2.4.htm
http://blog.chinaunix.net/uid-25940216-id-3118066.html

http://canbeatle.iteye.com/blog/891319

http://blog.21ic.com/user1/4132/archives/2010/75445.html

linux 文件描述符表 打开文件表 inode vnode的更多相关文章

  1. 进程表/文件表/inode/vnode

    一般我们讲,都说进程有文件描述符表,文件描述符表中的指针指向某个inode,这中间省略了file,dentry对象,对准确理解VFS结构无益,本文结合网络所查,并根据APUE8.3和LKD13.11章 ...

  2. Linux操作系统中打开文件数量的查看方法

    Linux操作系统中打开文件数量的查看方法ulimit -n 4096也就是限制用户的最大文件打开数为4096个 在网上查了关于怎么查看文件打开数的文章大致有两种说法/proc/sys/fs/file ...

  3. Linux下Firefox打开文件jnlp文件

    ubuntu(linux)打开jnlp文件 咘咘 2019-05-20 15:12:48 1331 收藏展开 前提条件是安装有java环境.whereis java 查看自己java安装目录.本人是在 ...

  4. 【Linux】系统打开文件最大数量限制(进程打开的最大文件句柄数设置)

    利用ulimit命令可以对资源的可用性进行控制. -H选项和-S选项分别表示对给定资源的硬限制(hard limit)和软限制(soft limit)进行设置. 硬限制(hard limit)一旦被设 ...

  5. C# 打开文件或打开文件夹

    直接打开指定的文件 System.Diagnostics.Process.Start(v_OpenFilePath); 直接打开目录 string v_OpenFolderPath = @" ...

  6. ppt标签打开文件 word标签打开文件 窗口打开文件 粘贴默认方式

    ppt标签打开文件 word标签打开文件 word窗口打开文件 ppt粘贴默认方式 word粘贴默认方式 ppt粘贴默认方式 只保留文本 == 通过 视图 切换窗口. == 层叠  样式 如下. == ...

  7. Linux记录-lsof打开文件工具常用操作

    lsof `which httpd` //那个进程在使用apache的可执行文件 lsof /etc/passwd //那个进程在占用/etc/passwd lsof /dev/hda6 //那个进程 ...

  8. Winform中上传、下载文件选择打开文件的位置

    打开将要上传的文件 var fileName="";OpenFileDialog fileDialog = new OpenFileDialog(); fileDialog.Mul ...

  9. 解决centos无法上传文件和打开文件夹

    使用yum搭建了ftp服务..yum的使用参考:http://blog.csdn.net/enson16855/article/details/9140623 windows使用FileZilla连接 ...

随机推荐

  1. 9、共享变量(Broadcast Variable和Accumulator)

    一.共享变量 1.共享变量工作原理 Spark一个非常重要的特性就是共享变量. 默认情况下,如果在一个算子的函数中使用到了某个外部的变量,那么这个变量的值会被拷贝到每个task中.此时每个task只能 ...

  2. shell命令的原理

    https://blog.csdn.net/m0_37925202/article/details/80258974 https://blog.csdn.net/a15929748502/articl ...

  3. python 装饰器demo

    本质就是一个函数,这个函数符合闭包语法结构,可以在函数不需要改变任何代码情况下增加额外功装饰器的返回值是一个函数的引用 功能:1.引入日志:2.函数执行时间统计:3.执行函数前预备处理:4.执行函数后 ...

  4. [FUZZ]文件上传fuzz字典生成脚本—使用方法

    文件上传fuzz字典生成脚本-使用方法 原作者:c0ny1 项目地址:https://github.com/c0ny1/upload-fuzz-dic-builder 项目预览效果图: 帮助手册: 脚 ...

  5. Centos7变动

    Nmtui:网络配置图形界面 Systemctl:管理systemd的单元 Service:系统服务 Socket:进程间的通信 Busname: Target:多个unit构成的组,运行级别 Sna ...

  6. JS中注入eval, Function等系统函数截获动态代码

    正文 现在很多网站都上了各种前端反爬手段,无论手段如何,最重要的是要把包含反爬手段的前端javascript代码加密隐藏起来,然后在运行时实时解密动态执行. 动态执行js代码无非两种方法,即eval和 ...

  7. 关于PHP中token的生成的解析

    背景 很多时候我们需要用 token 来作为一些标识, 比如: 一个用户登录后的认证标识. 实现方式 md5 的方式: $v = 1; // 自己定义的 需要hash 的value 值 $key = ...

  8. 【Json】Json分词器

    package com.hy; import java.io.BufferedReader; import java.io.FileInputStream; import java.io.FileNo ...

  9. Flutter -------- 新手 WanAndroid 项目练习

    一个简单Flutter项目wanandroid,先前用Kotlin来开发过,适合新手练习. 用到的库 包含功能: http+数据解析 网络请求数据列表展示 Banner轮播 WebView跳转详情 D ...

  10. PHP中Cookie与 Session

    在非常多时候,我们需要跟踪浏览者在整个网站的活动,对他们身份进行自动或半自动的识别(也就是平时常说的网站登陆之类的功能),这时候,我们常采用  Cookie与 Session 来跟踪和判断. Sess ...