Unix进程对打开文件的管理
看下图:
说明:
系统维护一个进程表,一个进程对应进程表里面的一个进程项,进程项里包含了此进程打开的所有文件的文件描述符表信息。
系统为所有打开的文件维护一张文件表,每个进程的每一个文件描述符对应一个文件表项。
文件表项里有一个v节点表项指针,指向v节点表。v节点表在内存中,一个v节点表项对应一个文件,存储了文件一些属性信息。
举例,我们只看前两个进程:
最上面进程打开文件a,对应fd0,打开文件b,对应fd1;
第二个进程打开文件a,对应fd0,然后用dup(fd0)返回得到fd1。
文件表项1对应进程1打开的文件a;
文件表项2对应进程1打开的文件b;
文件表项3对应进程2打开的文件a。
v节点表项1记录了文件a的属性;
v节点表项2记录了文件b的属性。
结论:
同一个进程下的不同文件描述符可能指向同一个文件表项(比如下面将要讲的dup函数返回的新描述符和原描述符就指向同一个文件表项)。
不同进程打开的即使是相同的文件,也对应不同的文件表项,因为要各自拥有自己的文件偏移量。
但是一个文件只有一个v节点表项,所以不同文件表项可能会指向同一个v节点表项(只要是同一个文件)。
复制文件描述符:
#include <unistd.h>
int dup(int filedes);
int dup2(int filedes, int filedes2);
//成功则返回新的文件描述符,出错返回-1
dup返回的文件描述符一定为当前可用文件描述符的最小数值。
dup2可以指定新描述符的数值,若filedes2已经打开,则先将其关闭,若filedes2 == filedes,则返回filedes2而不关闭。