对于下面这句代码大家一定不陌生:

“ >” 将输出重定向至test.txt文件,但是为什么>能重定向输出,其中的原理又是什么呢?接下来就说说IO重定向。

1.描述符表(descriptor table)– 每个进程都有各自的表

file descriptor(fd),当调用open函数时会返回这个文件的文件描述符fd,这个fd相当于一个索引,而一个进程可以打开多个文件,所以每个进程都有一个描述符表(fd就是这个表的索引)用于保存该进程打开的文件的索引。简而言之,fd就是描述符表的索引,而描述符表项中存的是每个文件表项的起始地址。

2.文件表(file table)– 所有进程共享

每个表项对应一个文件操作记录,其中记录了当前的访问位置,引用次数等。多个fd可以指向同一个文件表项(共享),多个文件表项可以指向同一个v-node(两个不相关的进程打开同一个文件)。

3.v-node表 — 所有进程共享

存在磁盘上面的文件有两个部分,一部分是数据,另一部分就是v-node,v-node记录了这个文件的相关信息,如文件大小,访问权限,上次访问时间等。当打开文件时操作系统会将这个文件的v-node加载进内存,对一个文件而言v-node只会被加载一次, 所有的进程都共享这些v-node。

4.三者之间的关系

为了更好理解上面所说的,先来看看下面这张图:

fd

多个fd可以指向同一个文件表项,这时会增加引用计数,当引用计数为0时,操作系统会删除这个表项。每个文件表项中存储了当前的文件指针指向的位置。不同的文件表项若打开了相同的文件,则一定指向相同的v-node表项。

5.IO重定向的原理

一般情况下,fd=0则表示标准输入,fd=1表示标准输出,fd=2表示标准错误输出。 使用“>”进行输出重定向的原理即将指向stdout的fd1改成指向test.txt即可,如下图:

fd1

将蓝线改成红线即可完成输出重定向至test.txt

6.再看fork

使用fork函数时,子进程继承了父进程的描述符表,也就是说子进程中拷贝了一份父进程的描述符表,并且将所有对应的文件表项的引用计数加1。

 

观看更多有关 的文章?

*

+
跳转到评论