文件描述符就是内核当中 fd_array 数组的下标,是一个正整数
我们写出如下代码,并在代码最后加上一个循环,让代码不要退出
运行程序,后查看当前进程
如下图所示:
文件描述符:
- 0–>标准输入
- 1–>标准输出
- 2–>标准错误
在进程中有一个结构体指针(struct file_struct* files),指向了一个结构体(struct files_struct),而在这个结构体(struct files_struct)中有一个数组,这个数组的下标就是文件描述符,数组的每个元素的类型是struct file*,struct file* 这个结构体指针指向 struct file这个结构体(保存了文件的元信息),而最终和磁盘打交道的就是struct file这个结构体
最小占用原则:在数组中找到当前没有被使用的最小的一个下标,作为新的文件描述符
如下代码所示,我们关闭了2,会发现fd不是3而是2
进程最大打开文件描述符个数是由操作系统中一个参数限制的,可以通过命令:
ulimit -a
查看到一个open files
,open files后面的值就是进程可以打开的最大文件描述符个数
最大文件描述符个数更改:
ulimit -n
我们可以先cd到 /usr/include目录下,在此目录下我们可以看到所有的头文件
我们在用vim打开stdio.h
此时我们就可以找到FILE
- FILE文件流指针是一个typedef之后的值,本质是一个结构体
- 在“/usr/include/stdio.h”目录下可以看到
而我们怎么才能查看FILE这个结构体中的内容呢?
我们可以通过grep "struct _IO_FILE {" . -R
命令进行搜索,此时我们会看到,这个结构体的位置在 ./libio.h
此时我们只需vim进入libio.h,在进行搜索即可找到
在struct _IO_FILE这个结构体中,我们可以看到读缓冲区
和写缓冲区
int _fileno;当中保存的内容就是文件描述符
在此我们可以更清楚的了解文件流指针的工作原理,如下图所示:
?????之前在进程终止的时候说的刷新缓冲区:指的是C库当中维护的读写缓冲区
?????借助上图我们可以理解:_exit()函数之所以不会刷新缓冲区,是因为_exit()函数是内核代码,直接操作内核结束结束了进程,而此时并不会通知上层的C库,所以,C库维护的缓冲区完全在无感知的情况下进程就终结了
- 文件流指针是一个结构体,在结构体内部保存了文件描述符
?- 文件描述符是一个正整数,其含义为fd_array数组的下标
?- 文件流指针维护了读写缓冲区
?> :清空重定向,将文件内容清空之后在重定向
测试如下:
我们vim一个abc文件,可以看到abc文件中的内容如下图所示:
然后我们使用 ls > abc 命令之后可以看到abc中的内容已经被清空重定向了
?>> :追加重定向,直接在文件的尾部进行重定向
测试如下:
我们对abc文件进行追加重定向,可以看到,直接在文件的尾巴进行了重定向
将 fd_array 数组当中的元素struct file* 指针的指向关系进行修改,改变成为其它的struct file结构体的地址
int dup2(int oldfd, int newfd);
通过man手册我们可以对dup2函数进行一些了解,我们会看到这样一段话
- newfd的值是拷贝于oldfd的值,及newfd的值来源于oldfd
?
eg:上文重定向原理图解中的过程可以写为:dup2(3,0);
(1) 如果必要,使用dup2进行重定向的时候,会先关闭newfd
?
- 必要:oldfd是正常的文件描述符
?- 如果oldfd不是一个有效的文件描述符,则不关闭newfd,重定向失败 eg:dup2(10,0) 没有文件描述符10
?- 如果oldfd是一个有效的文件描述符并且和newfd是相同的文件描述符数值,则dup2什么事情都不有干 eg:dup2(0,0);
(2) 将oldfd的值拷贝给newfd
注意:
? ? ? 一般C库函数写入文件时是全缓冲,而写入显示器是行缓存
? ? ? eg:“\n”==》行缓冲
本文分享自华为云社区《 架构可视化支撑系统演进探索 》原文作者无名小溪。 随着...
Afrikaans:af Albanian:sq Basque:eu Belarusian:be Bulgarian:bg Catalan:ca Ch...
ajax传送json格式数据,关键是指定contentType,data要是json格式 如果是restful...
Eval 计算一个表达式的值并返回结果。 语法:[result = ]eval_r(expression_r) e...
一、导读 本文主要介绍Redhat7.6系统安装oracle 12201版本RAC的一些坑以及避坑方...
如果你想对使用手机,平板电脑和辅助技术的用户隐藏某些内容,而只对键盘用户显...
Linux 发行版的爱好者们又有全新的 Linux 可以体验了,日前一款名为 TeLOS 的 Li...
今天给大家分享四个在实际开发中,比较实用的SQL Server脚本函数,希望对大家能...
最近在和团队规划OKR目标的时候,我们讨论了很多问题,我先抛砖引玉,列举了一些...
一. RabbitMQ 简介 MQ全称为Message Queue, 消息队列(MQ)是一种应用程序对应用...