目录
1.重定向
1.1dup2
2.缓冲区
2.1什么是缓冲区
2.2为什么存在缓冲区
2.3缓冲区的刷新策略
2.4查看源码
3.0/1/2
3.1 0/1/2是什么&为什么存在
3.2 2和1区别
3.3 2为什么存在
1.重定向
- 重定向的本质:是在内核中改变文件描述符表特定下标的内容和上层无关❗、
- 上层不变,OS只给上层一个数字。下标也不变,主要是变文件描述符表(指针数组)元素内容。
- 重定向是OS系统级别的修改,struct files_struct是内核数据结构。要修改文件描述符表中元素(指针/指向)必须要OS给用户提供系统调用。
1.1dup2
- man 2 dup2
- int dup2(int oldfd, int newfd);
- dup2可以在底层帮助完成两个文件描述符表(指针数组)的元素值拷贝。
- 做两个整数的拷贝(fd)本质:文件描述符表(指针数组)下标fd对应的数组元素(指针)内容的拷贝。
- dup2() makes newfd be the copy of oldfd
- 记忆:最后只会保留oldfd,也就是要重定向的内容
- >和>>二者区别是:打开的方式选项不同清空&追加 O_TRUNC&O_APPEND
- 重定向后 没有文件描述符指向的文件会被自动关闭。一个文件有两个文件描述符指向。
- struct file内部会存在int ref_count(引用技术)
- 文件有几个指向ref_count就是几个。为0的文件会自动关闭。
- int ref_count(引用技术):就是有多少个指针指向文件对象。图
【输出重定向>】
【追加重定向>>】
- shell进程在启动的时候,就会在/dev/pts创建设备文件。(默认打开的显示器/键盘等)
- 若我们新打开一个窗口(终端),这个终端也是进程打开的设备文件,也会在/dev/pts目录下创建自己对应设备文件。(字符设备)Linux底下一切皆文件。
- C语言编程使用printf时,默认会在当前进程所处的终端打印数据。(3号终端)
- 新打开的终端是2号。将数据从3号终端重定向2号终端。
2.缓冲区
2.1什么是缓冲区
所谓缓存区就是把数据临时放在一段内存空间里。
2.2为什么存在缓冲区
- 计算机中存在很多缓冲区,既有用户级的缓冲区,又有内核级的缓冲区。每一种缓冲区都有自己特殊的作用。注❗缓冲区存在两种益处
- 每一个文件都有一份自己的缓冲区❗
解耦:
- 内核缓存刷新到外设:用户把数据交给OS的内核缓冲区,刷新到外设都不用管了。(语言和硬件解耦了)
- 用户级缓存刷新到内核缓存:printf只需要把数据交给用户缓存区,不用管C语言怎么把数据刷新到内核的。(用户和系统解耦了)
提高效率(❗重点谈)提高效率是提高使用者的效率
用户printf☞用户级缓存☞内核级缓存☞外设
- 调用系统调用是有成本的(系统调用是需要OS配合,OS很忙的)所以少调用,效率就高。
- 编程语言是需要注重用户体验的,只有把用户体验服务搞好了,才会有更多的人去使用这门语言。
- 编程语言提供的接口,只需要把数据交给缓冲区,立刻旧可以返回。缓冲区的存在是提高使用者的效率。有缓冲区的存在,是提高printf/fprintf等接口的使用效率。
- 编程语言的接口使用就会比较快(因为只是写道缓存中,没有到内核),用户体验好。
- 使用语言提供的接口,在用户级缓存积累多次。等待OS配合一次性就刷新大量数据到内核,提高OS整体的效率。
- 内核级缓存存在提供使用系统调用的人的体验(因为外设硬件很慢)
- 语言为用户考虑,系统为语言考虑。
- 综上:提高使用者的效率。提高刷新IO的效率。给上层提供高效的IO体验,间接提高整体的效率。
2.3缓冲区的刷新策略
立即刷新: 相当于没有缓存,还多了一次拷贝(常见),数据立即从内核同步到外设。
语言:fflush
系统:man 2 fsync
行刷新:显示器是行刷新。照顾用户的查看习惯。
全缓冲:缓冲区满了才刷新。普通文件。
特殊情况:
进程在退出时,无论是用户/内核级的缓存,系统和语言都会自动刷新。
强制刷新(ffush/fsync)
注❗:缓冲区的刷新策略和是 用户级缓冲区。内核级不关心。
不同的平台对刷新的策略是不一样的
【进程退出:exit和_exit】
【进度条:\n和fflus】
【看代码☞说明现象】
2.4查看源码
3.0/1/2
3.1 0/1/2是什么&为什么存在
- 0:标准输入,键盘。
- 1:标准输出,显示器。
- 2:标准错误,显示器。
- 程序需要和人交互的,所以必须要从特定的设备获取数据,对数据处理之后,输出结果。方便用户动态的获取数据和查看数据。
3.2 2和1区别
- fd为1/2的都指向同一个显示器文件(往同一个终端打印)。
- 当把数据往显示器上打印:一切正常。
- 当把数据重定向到普通文件中:
- 1号下标对应内容改变了,2号下标对应内容没有改变。
- > 标准输出重定向,只会改变1号下标的对应的内容。标准输出会重定向,标准错误不会重定向。图
【往显示器上打印】
【输出重定向>】
3.3 2为什么存在
- 当编程的时候。会产生两类消息,正确的消息和错误的消息。为了区分这两类消息。
- 正确的消息往1里面打印。错误的消息往2里面打印即可。
- 只需要做一次重定向就可以把正确和错误的信息在文件层面上分开即可。
【就想把1和2要打印内容一起重定向一个文件中】