open表和closed表_描述符表、文件表与 v-node 表

本文详细介绍了文件描述符、文件表和v-node表在操作系统中的作用和关系。文件描述符用于标识进程中的打开文件,由open()函数返回。每个进程有自己的描述符表,而所有进程共享一个文件表,其中记录了文件状态,如位置、引用计数等。文件表的引用计数在close()时递减,为0时删除。v-node表存储文件元数据,被多个文件表项可能指向。dup2()函数可以复制描述符,导致多个描述符指向同一文件表项。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

描述符表(descriptor table)

描述符 (file descriptor) 代表进程中打开的文件, 通常由 open() 函数返回。 另外 shell 中启动的进程默认会打开 3 个描述符, 分别是:

  • 标准输入, 对应 STDIN_FILENO (值为 0)
  • 标准输出, 对应 STDOUT_FILENO (值为 1)
  • 标准错误, 对应 STDERR_FILENO (值为 2)

每个进程都有自己的描述符表,用以记录进程中所有打开的文件。一个描述符对应于一个打开的文件。

当调用 close() 函数时,系统会回收对应的描述符。

文件表(file table)

所有进程共享一个文件表

文件表记录了被打开文件的一些状态信息, 包括 文件位置引用计数以及指向v-node表的指针等

  • 所有打开的文件都有一个文件位置,表示下一次读或写的起始位置。 seek, read, write 函数都可以修改该文件位置。
  • 所有进程共享同一个文件表。文件表中的一个表项可能会被多个描述符指向,引用计数用来表示当前有多少个描述符指向该文件表表项。当调用 close() 函数时,系统会将描述符对应的文件表表项的引用计数减1,然后如果引用计数已经为0,则系统会删除此文件表表项。

当 shell 启动一个进程时,打开了 3 个描述符,每个描述符都指向了一个文件表表项。如下图:

19384d32a3bff5a2a2411738b7e2187e.png

当程序调用 fork() 函数时, 则会出现(不同进程的)多个描述符对应于同一个文件表表项的情况:

void main() {
    int fd = open(name, O_RDONLY, 0);
    fork();
    // ...
}

在 fork() 调用返回之后, 文件表和描述符表的关系如下:

9080bb422d3de41c7b09f7dff832202c.png

这里再介绍一个 dup2() 函数:

int dup2(int oldfd, int newfd);

dup2 函数用 oldfd 的内容替换掉 newfd 的内容。如果 newfd 是打开的,则会再替换之前先关闭 newfd。(思考一下,系统的重定向可能就是用这个函数实现的呢)

当程序调用 dup2 时,也会出现(同一个进程中的)多个描述符指向同一个文件表表项的情况:

void main() {
    int fd = open(name, O_RDONLY, 0);
    dup2(fd, STDOUT_FILENO);
}
// ...

在 dup2() 调用返回之后, 文件表和描述符表的关系如下:

6a926ac5e1be2369e378bc1cb87a617b.png

v-node 表(v-node table)

所有进程共享同一个 v-node 表

一个 v-node 表的表项对应于一个文件。它记录了文件的元数据信息。包括文件权限,文件大小, 文件类型等信息。

v-node 中的一个表项可能被多个文件表表项指向。

当对同一个文件调用多次 open() 函数,那么会产生多个文件表表项,但是只有一个 v-node 表表项。 如下面的程序:

int fd1 = open("hello.txt", O_RDONLY, 0);
int fd2 = open("hello.txt", O_RDONLY, 0);

它只有一个 v-node 表项,但却有两个描述符表表项和两个文件表表项:

9920812073abc377e74c005b8334afaf.png

参考书籍: 《深入理解计算机系统》

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值