目标:研究fd的分配规则
方式:做实验
我们写一段代码,需要实现的功能如下:利用系统调用接口实现读入字符,并且把读入的字符打印在屏幕上。
实验1
我们需要用到read()函数。
read是系统调用接口,头文件和用法如下:
实现的代码如下:
code
运行结果:
此时我们发现,我们程序执行之后我们输什么字符都会被打印出来,最后我们回车也被以空行的形式打印出来了(回车符也是字符):
我们如果不想回车符也被打印出来,那我们就把buffer的最后一个值去掉:
运行结果:
为了配套,现在不用printf输出,用write()函数来输出:
实验1结论:
0,1,2只是数字,但是在这里却可以实现输入输出报错的功能,因此我们可以得出结论:
实验2
实验目的:因为上面的实验得到结论进程默认打开了0,1,2三个信号描述符,现在我们在创建文件之前手动关掉0号文件描述符,然后再去创建文件,看看此时新创建的文件的文件描述符是几号。
实验过程:
实验结果:
发现关闭了0号文件描述符,新创建的文件描述符仍然是0号文件描述符。
现在我们再依次关闭1号文件描述符和2号文件描述符,看看会得到什么结果:
关闭1号文件描述符运行结果:
什么都没有输出(因为1号文件描述符是stdout):
关闭2号文件描述符运行结果:
通过这个实验我们可以得出一个结论:哪个文件描述符没用就会优先分配最小的那个闲置的文件描述符,结合前面实验1结论如下:
结论:
实验3
首先我们关闭文件描述符1,然后打开文件log.txt,最后我们向显示器打印出此时的fd值:
我们发现运行完a.out之后屏幕上什么都没有打印出来,此刻我们打印文件log.txt,发现把log.txt被分配的描述符是1:
1是标准输出文件显示器的文件描述符,但是分配给文件log.txt的文件描述符确是1.
我们来看看这中间发生了什么:
因为0号文件描述符已经被用掉了,而显示器被关掉了,1号文件描述符被释放了,变为了闲置状态。而此时我们刚好创建了log.txt文件,所以1号文件描述符就被分配给了log.txt文件:
平时我们说printf()函数是向显示器上打印内容,因为printf()函数绑定的是stdout,实际上stdout绑定的是1号文件描述符,1号文件描述符分配给哪个文件,printf()就向哪个文件输出内容。如果分配给显示器文件,那么就向显示器打印内容,如果分配给log.txt文件,那么就会朝log.txt文件输出内容。
这句代码是什么意思呢?:我们把这一行注释掉再执行:
发现log.txt文件什么都打印不出来,这又是为什么呢?
首先我们的数据不会直接写到文件里,而是先读入到c语言提供的缓冲区,c语言再通过fd把数据提供给内核,但是我们代码最后执行了 close(fd);把通道给关掉了,因此数据就传不过去了,所以需要我们刷新一下: