【Linux】:重定向和用户缓冲区

重定向和用户缓冲区

文件描述符对应匹配规则:从0下标开始,寻找最小的没有被使用的数组位置,它就是新的文件描述符(fd)。

一.输出重定向

1.现象

在这里我们向1号文件内写入字符串,1号文件本来是显示器,那么我们将1号文件关闭后再向1号文件写入会发生什么呢?

我们可以看到屏幕并没有打印字符串,很正常因为我们把屏幕关闭了,但它却把内容写到了log.txt内,这个现象就是输出重定向。

当我们把1号文件关闭后再创建了一个log.txt文件,该文件就会占据1号文件的位置,那么当我们向1号文件写入时,自然就写入到了log.txt里。

2.系统调用接口

显然对于先关闭再打开这样的操作还是很麻烦,其实只需要struct file*fd_array[]数组里对应下标的值拷贝一份放到目标下标里,就可以完成一次重定向。

二.缓冲区

1.引子

这里没什么问题,接下来将代码改一下。

直接运行程序也没有出现问题。

这里为什么重定向到另一个文件就变成了7行内容呢?再仔细观察可以发现c接口的打印了两次,而系统接口的只打印了一次。由于我们只加了一个fork函数,所以这个现象必定和fork有关。 想要解释这个现象需要花费一系列的功夫,慢慢说来。

2.刷新

再次更改代码

新增一个close并且去掉了/n,来看看现象。

结果是没有任何输出(当然将close去掉就能打印出来)。首先这个缓冲区一定不在操作系统内部。因为如果在内部,当close时,缓冲区的数据就会直接被刷新到磁盘里。而write写入能看到,是因为write直接写到内部缓冲区里了。

而C语言它会自己提供一个缓冲区,这个缓冲区是语言层面的。而当等到合适的时候,例如:遇到/n,fclose...它才会调用write接口将其发送到内部缓冲区里。而这种操作被称为刷新。 用户刷新的本质就是将数据用write写入到内核里。目前我们认为只有将数据刷新到了内核,数据就可以找到硬件了。

应用层的三种刷新方式

在平常我们写printf函数时不带/n也能打印出来,是因为在进程退出时,缓冲区也会进行刷新。

而在退出前关闭文件就不会进行刷新。

前文说到缓冲区在C语言里,这样很笼统。其实具体在FILE这个结构体内,而FILE是属于语言层面的,那么每打开一个文件就会创建一个FILE结构体,也会多一个缓冲区。

三.回答引例

因为在fork时,子进程与父进程公用同一份代码,同时在最开始时共用一份数据,如果需要,子进程才会发生写时拷贝复制数据并更改。那么在此之前父进程的缓冲区里已经有了3条代码(注意write是系统调用接口,直接写入了内核),所以子进程在创建时的缓冲区也有3条代码(注意是写入普通文件,是全缓冲),当子进程结束时将这3条写入文件,父进程结束时也将这3条写入文件,(注意当一个进程刷新后,数据发生了变化,另一个进程就会发生写时拷贝,所以这里父子进程会刷新3条)所以该文件就会有7条代码了(write的首先写入了)。

相关推荐
mubeibeinv4 分钟前
项目搭建+图片(添加+图片)
java·服务器·前端
dessler8 分钟前
Docker-如何启动docker
运维·docker·云原生·容器·eureka
zhy295638 分钟前
【DOCKER】基于DOCKER的服务之DUFS
运维·docker·容器·dufs
无为之士14 分钟前
Linux自动备份Mysql数据库
linux·数据库·mysql
秋名山小桃子23 分钟前
Kunlun 2280服务器(ARM)Raid卡磁盘盘符漂移问题解决
运维·服务器
与君共勉1213824 分钟前
Nginx 负载均衡的实现
运维·服务器·nginx·负载均衡
岑梓铭30 分钟前
(CentOs系统虚拟机)Standalone模式下安装部署“基于Python编写”的Spark框架
linux·python·spark·centos
努力学习的小廉31 分钟前
深入了解Linux —— make和makefile自动化构建工具
linux·服务器·自动化
MZWeiei34 分钟前
Zookeeper基本命令解析
大数据·linux·运维·服务器·zookeeper
7yewh1 小时前
嵌入式Linux QT+OpenCV基于人脸识别的考勤系统 项目
linux·开发语言·arm开发·驱动开发·qt·opencv·嵌入式linux