内核使用了三种数据结构,它们之间的关系决定了在文件共享方面一个进程对另一个进程可能产生的影响。
(1) 每个进程在进程表中都有一个记录项,每个记录项中用fd 标志标识,可将其视为一个矢量。与每个文件描述符相关联的是:
(a) 文件描述符标志。
(b) 指向一个文件表项的指针。
(2) 内核为所有打开文件(open操作成功后)建立一个当前文件使用的记录,称为文件表项,顾名思义是放在一个文件表中的。每个文件表项包含:
(a) 文件状态标志(读、写、增写、同步、非阻塞等)。
(b) 当前文件位移量。
(c) 指向该文件v节点表项的指针。
(3) 文件(或设备)(只要被某个进程打开了)都有一个v节点结构。v节点包含了文件类型和对此文件进行各种操作的函数的指针信息。对于大多数文件, v节点还包含了该文件的i节点(索引节点,在一篇专门介绍)。这些信息是在打开文件时从盘上读入内存的,所以所有关于文件的信息都是快速可供使用的。例如, i节点包含了文件的所有者、文件长度、文件所在的设备、指向文件在盘上所使用的实际数据块的指针等等
上面的图显示了进程的三张表之间的关系。该进程有两个不同的打开文件,一个文件打开为标准输入(文件描述符0),另一个打开为标准输出(文件描述符为1)。
如果两个独立进程各自打开了同一文件,则有下面图所示的安排。
我们假定第一个进程使该文件在文件描述符3上打开,而另一个进程则使此文件在文件描述符4上打开。打开此文件的每个进程都得到一个文件表项,但对一个给定的文件只有一个v节点表项。每个进程都有自己的文件表项的一个理由是:这种安排使每个进程都有它自己的对该文件的当前位移量来记录对文件的操作情况。
给出了这些数据结构后,现在对前面所述的操作作进一步说明。
• 在完成每个w r i t e后,在文件表项中的当前文件位移量即增加所写的字节数。如果这使当前文件位移量超过了当前文件长度,则在i节点表项中的当前文件长度更新成当前文件位移量(也就是该文件加长了)。
• 如果用O _ A P P E N D标志打开了一个文件,则相应标志也被设置到文件表项的文件状态标志中。每次对这种具有添写标志的文件执行写操作时,在文件表项中的当前文件位移量首先被更新到对应i节点表项中的文件长度。这就使得每次写的数据都添加到文件的当前尾端处。
• lseek函数只修改文件表项中的当前文件位移量,没有进行任何I / O操作。
• 若一个文件用l s e e k被定位到文件当前的尾端,则文件表项中的当前文件位移量被设置为i节点表项中的当前文件长度。
可能有多个文件描述符项指向同一文件表项。注意,文件描述符标志和文件状态标志在作用范围方面的区别,前者只用于一个进程的一个描述符,而后者则适用于指向该给定文件表项的任何进程中的所有描述符。
每个进程都有它自己的文件表项,其中也有它自己的当前文件位移量。但是,当多个进程写同一文件时,则可能产生预期不到的结果。为了说明如何避免这种情况,需要理解原子操作的概念。
posted on 2009-10-06 12:34
月光记忆 阅读(352)
评论(0) 编辑 收藏 所属分类:
c进程间通信