APUE学习笔记-文件共享
文件共享
Unix系统支持在不同的进程间共享打开文件。其结构如下所示:
内核使用了三种数据结构,它们之间的关系决定了在文件共享方面一个进程对另一个进程的影响。
-
每个进程在进程表中都有一个记录项,在每个记录项中都有一张打开的文件描述符表,每个描述符占用一项。与每个文件描述符相关联的是:
- 文件描述符,文件描述符;
- 指向一个文件表项的指针;
-
内核为所有打开的文件维持一张文件表。每个文件表包含的信息如下:
- 文件状态标志(读、写、同步、非堵塞等);
- 当前文件的偏移量;
- 指向该文件v节点表项的指针;
-
每个打开的文件(或设备)都有一个v节点结构。v节点包含了文件类型和对此文件进行各种操作的函数的指针信息。对于大多数文件,还包括了i节点(索引节点)。这些信息在打开时,从磁盘上读入内存,所以所有的关于文件的信息都是快速可供使用的。例如,i节点包括了文件所有者、文件长度、文件所在的设备、指向文件在磁盘上所使用的实际数据块指针。
如果多个进程打开同一个文件,那么此时的共享结构如下:
如果两个独立进程各自打开了同一个文件,打开此文件的每一个进程得到一个文件表项,但对于一个给定的文件只有一个v节点表项。每个进程都有自己的文件表项的一个理由:这种安排使每个进程都有它自己对该文件的当前偏移量。
- 在完成每个write之后,在文件表项中的当前文件偏移量就是当前所写入增加的字节数。如果这使当前文件的偏移量超过了当前文件的长度,则在i节点表项中的当前文件长度被设置为当前文件偏移量。
- 如果使用O_APPEND标志打开一个文件,则相应标志也被设置到文件表项的文件状态标志中。每次对这种具有O_APPEND标志的文件执行写操作时,在文件表项中的当前文件偏移量首先被设置为i节点的文件长度。这就使得每次写数据都添加到文件的末尾。
- lseek函数只是修改了文件表项的当前文件偏移量,没有进行I/O操作。
- 若一个文件用lseek被定位到文件当前的末尾,则文件表项中当前文件偏移量被设置为i节点的当前文件长度。
备注: - 可能多个文件描述符指向同一个文件表项;
- 文件描述符和文件表项文件状态标志在作用范围是有区别的。文件描述符只用于一个进程的一个描述符,而后者则适用于指向该文件表项的任何进程中的所有描述符。