赞
踩
描述符 (file descriptor) 代表进程中打开的文件, 通常由 open() 函数返回。 另外 shell 中启动的进程默认会打开 3 个描述符, 分别是:
每个进程都有自己的描述符表,用以记录进程中所有打开的文件。一个描述符对应于一个打开的文件。
当调用 close() 函数时,系统会回收对应的描述符。
所有进程共享一个文件表。
文件表记录了被打开文件的一些状态信息, 包括 文件位置、引用计数以及指向v-node表的指针等
当 shell 启动一个进程时,打开了 3 个描述符,每个描述符都指向了一个文件表表项。如下图:
当程序调用 fork() 函数时, 则会出现(不同进程的)多个描述符对应于同一个文件表表项的情况:
- void main() {
- int fd = open(name, O_RDONLY, 0);
- fork();
- // ...
- }
在 fork() 调用返回之后, 文件表和描述符表的关系如下:
这里再介绍一个 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() 调用返回之后, 文件表和描述符表的关系如下:
所有进程共享同一个 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 表项,但却有两个描述符表表项和两个文件表表项:
参考书籍: 《深入理解计算机系统》
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。