打开文件描述符表
这个表由内核维护,所有进程共享。存放的是已打开的文件的描述符。该描述符记录了文件的地址(已读取至内存中)、引用计数等信息。
- 写入文件时,先将新数据写入文件缓冲区(也就是先修改内存中的文件拷贝),再将缓冲区的内容写入到磁盘。
- 关闭文件时,引用计数递减,当引用计数归0时,将文件缓冲区从内存中释放,同时该描述符标记为删除。
- 一个系统能同时打开的文件数量是有限制的。
文件描述符表
每个进程在创建之初都会初始化一个文件描述符表fds[1024]
,这个表是一个数组,长度通常为1024。fds
中的文件描述符类似于一个索引,指向的是所有进程共享的打开文件描述符表。
- 不同文件描述符可以指向同一个打开文件描述符表项。
- 该表的前3个文件描述符
fds[0]
、fds[1]
、fds[2]
在创建时被分别初始化为STDIN_FILENO
,STDOUT_FILENO
,STDERR_FILENO
,即标准输入,标准输出,标准错误。不严谨的解释:对STDIN_FILENO的读操作,相当于读取键盘输入;对STDOUT_FILENO的写操作,相当于将字符打印到终端;对STDERR_FILENO的读操作相当于获取错误信息。
Linux中一切皆文件,键盘、终端等设备通过文件的形式挂载到文件系统上,通过文件系统统一管理。
输入输出重定向
当命令行输入一个”echo hello, yui > hello.txt”的命令时,实际上经历了以下过程:
- 系统打开
hello.txt
,并获得描述符 - 运行命令行的进程调用
fork
创建子进程 - 由于”>”的存在,子进程的文件描述符fds[2],即
STDOUT_FILENO
被修改为了文件hello.txt
,修改过程由dup2
函数实现 - 子进程执行
echo
内容,“hello, yui”输出至fds[2]指向的文件。