文件描述符标志/文件表项

  内核使用三种数据结构表示打开的文件,它们之间的关系决定了在文件共享方面一个进程对另外一个进程可能产生的影响。数据结构

1>每一个进程在进程表中都有一个记录项,记录项中包含有一张打开文件描述符表,可将其视为一个矢量,每一个描述项占用一项。与每一个文件描述符相关联的是:函数

  1. 文件描述符标志(close-on-exec)(每一个进程独有)
  2. 指向一个文件表项的指针

   注:其中close-on-exec标志,若是某个文件符设置了该标志,fcntl(fd, F_SETFD, 1), 则在该进程调用exec函数以前为exec族函数关闭对应的文件描述符。spa

2>内核为全部打开文件维持一张文件表项。每一个文件表项包含:指针

  1. 文件状态标志:读、写、添写、同步、非阻塞等(任何进程中的全部描述符均可指向同一个文件状态标志)
  2. 当前文件偏移量
  3. 指向该文件v节点表项的指针

   注:在文件表或者v索引节点中都有索引计数,引用计数为0的时候,文件引用为0的时候就能够收回此表项blog

    fork后父子进程各自的每个打开的文件描述符共享同一个文件表项索引

3>每一个打开文件(或设备)都有个v节点结构。v节点包含了文件类型和对此文件进行各类操做的函数指针。 对于大多数文件,v节点还包含了该文件的i节点(索引节点)。这些信息是在打开文件时从磁盘上读入内存的,因此全部关于文件的信息都是快速可供使用的。进程

例如:i节点包含了文件的全部者、文件长度、文件所在设备、只想文件实际数据块在磁盘上所在位置的指针等等。内存

注:Linux没有使用v节点,而是使用了通用的i节点结构。虽然这两种实现有所不一样,但在概念上,v节点和i节点是同样的。二者都指向文件系统所特有的i节点结构。同步

  

  两个独立进程各自打开同一个文件(下图),此图中能够看出,对于同一个文件,打开该文件的每一个进程都获得一个文件表项,但对一个给定的文件只有一个v节点表项。而每一个进程都有本身的文件表项的一个理由是:使每一个进程都有它本身的对该文件的当前偏移量。it

  1. 每一个write后,在文件表项中的当前文件偏移量既增长所写入的字节数,若是这致使文件偏移量超出了当前文件长度,则将i节点表项中的当前文件长度设置为当前文件偏移量(即文件长度增长)
  2. 若是用O_APPEND标志打开了一个文件,则相应标志也被设置到文件表项的文件状态标志中,每次对这种具备追加写标志的文件执行写操做时,文件表项中的当前文件偏移量首先会被设置为i节点表项中的文件长度,这就使得每次写入的数据都追加到文件的当前的尾端处
  3. 若一个文件用lseek定位到文件的当前尾端,则文件表项中的当前文件偏移量被设置为i节点表项中当前文件长度(与O_APPEND标志打开是不一样的)
  4. lseek函数只修改文件表项中的当前文件偏移量,不进行任何I/O操做

  dup后的文件表项

原子操做:

  由踱步组成的一个操做,若是该操做原子地执行,要么执行完全部的步骤,要么一步也不执行,不可能只执行全部步骤的一个子集。

相关文章
相关标签/搜索