fd的分配规则

fd的分配规则

  • stdin 标准输入
  • stdrerr 标准错误
  • stdout 标准输出
    • dup2 函数
  • fflush 刷新缓冲区

我们之前学习过了文件操作中一个非常重要的东西——文件描述符(file descripter),我们直接通过fd来对文件进行操作,而且我们也知道,操作系统会给我们打开三个默认的fd——标准输入,输出,错误。我们今天来看看这三个东西的规律:

stdin 标准输入

stdin,标准输入,占用文件操作符表的0号下标:
在这里插入图片描述我们之前说过,操作系统下一切皆文件,我们的stdin也可以看做是一个文件。

我们先正常创建一个文件,看看这个时候的fd:
fd的分配规则_第1张图片在这里插入图片描述
我们这个时候可以尝试把stdin对应的fd下标给关闭:
fd的分配规则_第2张图片
这个时候,我们再来看看stdin和我们文件的下标:
在这里插入图片描述这个时候我们发现我们新建我们新建文件的fd变为0了。

我么可以做一组实验,用scanf来做(因为stdin默认是键盘输入)
我们在代码中用scanf输入,首先我们先不关闭stdin:
fd的分配规则_第3张图片运行:
fd的分配规则_第4张图片这个时候会默认从键盘上读取。

这个时候我们把stdin关闭:
fd的分配规则_第5张图片这个时候再运行:
在这里插入图片描述
scanf并没有等待我输入,直接就结束了。

stdrerr 标准错误

我们也可以把stderror标准错误给关闭:
fd的分配规则_第6张图片
这个时候我们再来看:
fd的分配规则_第7张图片
我们新建的文件的fd是2。(这里说一下,stderr是错误日志,这样可以把错误信息和stdout的输出信息做区分,方便开发)

从上面的实验可以看出fd的分配规则就是优先使用下标小且空闲的数字

stdout 标准输出

我们还没有关闭过stdout,我们可以来试试:
fd的分配规则_第8张图片

然后执行:

在这里插入图片描述发现什么也没有,别慌,我们再加上一行这样的代码:
fd的分配规则_第9张图片
我们再来运行:
fd的分配规则_第10张图片
还是什么都没有,但是我们这次到My_log.txt中去看看:
在这里插入图片描述
发现printf并没有向屏幕打印而是向My_log.txt中打印了。这个有点像我们的“重定向”操作。

那这个是什么原理呢?其实我们这三个标准流实质上都是文件,文件描述符表的0,1,2号下标默认都是与这些设备连接:

fd的分配规则_第11张图片
现在假设我有创建一个新文件,并且我关闭了下标1,这时候新创建的文件的下标会占据1号位置,并且1号位置的连接改变到我新创建的文件上去:
fd的分配规则_第12张图片这个时候我们再调用printf,我们的printf只认识1,这个数字,这个时候1的下标是连接的My_log.txt,所以我们打印的内容会全部跑到My_log.txt中。

其实我们有专门的函数来帮助我们完成文件描述符表下标的覆盖:dup2

dup2 函数

我们先正常创建文件,然后正常打印:
fd的分配规则_第13张图片fd的分配规则_第14张图片
我们发现是可以正常显示的,这个时候如果我们不想让它往显示器上打印,我们就可以调用dup2函数:
fd的分配规则_第15张图片
dup2函数的功能是让新的fd下标被旧的fd下标所覆盖,我们可以演示一下:
fd的分配规则_第16张图片fd的分配规则_第17张图片这个时候我们发现printf往My_log.txt中打印了,跟我们之前的操作达到的效果一样。

我们可以用这个来模拟实现一个重定向功能,这个可以结合我们之前的知识做一个迷你的shell,这个我们之后再说。

fflush 刷新缓冲区

我们还有一个问题,就是我们之前没有加上fflush这行代码,我们什么也没看到,但是加上之后我们就看到了printf的打印结果,这是为什么呢?

我们要注意一点,我们所有的打印操作并不是一来就把内容打印到屏幕上,我们打印的内容会先放到一个区域,等到这个区域有一定量的数据之后,再一次性的向屏幕上打印,我们称这个区域为缓冲区
fd的分配规则_第18张图片
我们这里暂时了解一下,我们会拿一篇博客来讲解缓冲区

链接: https://blog.csdn.net/qq_67693066/article/details/135861958?csdn_share_tail=%7B%22type%22%3A%22blog%22%2C%22rType%22%3A%22article%22%2C%22rId%22%3A%22135861958%22%2C%22source%22%3A%22qq_67693066%22%7D

你可能感兴趣的:(linux,c语言)