Linux重定向原理与系统调用dup2
创始人
2024-03-21 05:04:17
0

🧸🧸🧸各位大佬大家好,我是猪皮兄弟🧸🧸🧸
在这里插入图片描述

文章目录

  • 一、重定向原理
    • ①输出重定向
    • ②输入重定向
  • 二、重定向的系统调用dup2
    • dup2输出重定向
  • 三、如何理解一切皆文件
  • 四.缓冲区
    • ①常见的缓冲区刷新策略
    • ②缓冲区的认识

一、重定向原理

在这里插入图片描述
因为文件类的接口都会去调用系统调用,因为对文件操作属于是文件管理,这部分内容是需要操作系统去完成的,因此在系统中,他是只认识fd这个数字的,并不知道FILE*这些,这些是上层封装出来的

①输出重定向

输出重定向的本质就是关掉stdout,也就是1号文件描述符,然后打开一个文件去占用这个文件描述符,然后输出即可

int main()
{char buffer[SIZE]="zhupi";close(1);//unistd.hint fd = open("log.txt",O_WRONLY|O_TRUNC|O_CREAT,0666);//打开文件,写|覆盖|没有则创建,权限为0666,真实权限需要集合权限掩码 0666&umaskif(fd<0) ...printf("fd:%d\n",fd);cout<

在这里插入图片描述

②输入重定向

输入重定向就是关掉stdin,也就是0号文件描述符,然后打开文件,占用0号文件描述符的位置,然后键盘输入,或者其他输入进去即可

int main()
{char buffer[64];close(0);int fd = open("log.txt",O_RDONLY)if(fd<0) ...printf("fd:%d\n",fd);fgets(buffer,sizeof buffer,stdin);printf(buffer);printf("\n");close(fd);return 0;
}

二、重定向的系统调用dup2

在这里插入图片描述
在这里插入图片描述

int dup2(int oldfd,int newfd);

dup2的作用是把oldfd拷贝到newfd,比如给log.txt创建到3的位置,然后将3拷贝给1,所以3是oldfd,1是newfd(这只是dup2的做法,其实我们close掉1,再open文件log.txt也是一样的效果)
在这里插入图片描述

dup2输出重定向

int main(int argc,char*argv[])
{printf("%d\n",argc);if(argc!=2){return 2;}int fd = open("log.txt",O_WROLNY|O_CREAT|O_TRUNC,0666);if(fd<0){perror("open");return 1;}dup2(fd,1);//old是fd,new是1,把fd拷贝给1fprintf(stdout,"%s\n",argv[1]);return 0;
}

当我们自己先close(1),再open log.txt,最后如果close(fd)的时候,发现并没有输出进log.txt,这是因为缓冲区的原因,还没有刷新进log.txt就被关了,这个到后面缓冲区的时候再谈,而dup2(fd,1)就不会,这是dup2的一种特性

三、如何理解一切皆文件

一切皆文件时Linux的设计哲学,体现在软件设计层面
那Linux是C写的,如何用C实现面向对象,甚至是运行时多态?

在这里插入图片描述
也就是用结构体来体现类的成员变量,然后存函数指针来找成员函数
所以说底层不同的硬件,对应不同的操作方法就可以了,每个设备实现的read和write不同

所以设计了一个struct_file来描述,在上层没有任何的硬件差别,看待所有文件的格式,都统一成了对file_struct的操作,所以在操作系统之上,Linux就有一切皆文件,Linux的这种管理模式,称作VFS(virtual file system虚拟文件系统)

在这里插入图片描述

四.缓冲区

①常见的缓冲区刷新策略

1.立即刷新
2.行刷新(行缓冲)
3,满刷新(全缓冲)

②缓冲区的认识

一般而言,行缓冲的设备一般是显示器
因为显示器是给用户看的,一方面照顾效率,一方面照顾用户体验
全缓冲的设备一般是磁盘文件
因为刷新到磁盘文件,因为用户是不需要马上看到的,更在乎的是效率

但是所有的设备,都倾向于全缓冲,因为缓冲区满了才刷新就意味着需要更少的IO操作->更少的访问外设,提高效率,其他属性层略是结合具体情况做的妥协(都倾向于缓冲区)

例:
在这里插入图片描述
因为向显示器打印是行缓冲,所以都能够正常打印,但当向文件中打印的时候,因为刷新策略是全缓冲(满刷新),所以在程序结束之前或者说缓冲区满之前并不会刷新到文件,所以子进程进行对父进程的拷贝,所以C的打印接口打印了两次,那么write系统调用为什么只打印一次呢?因为缓冲区是C标准库提供的,缓冲区并不是OS的,所以系统调用并不会用这套缓冲区的刷新策略,而且,父子进程所指向的缓冲区在打印之前也是指向的同一个,因为有写时拷贝。C的打印接口其实就是拷贝一份给缓冲区,然后缓冲区去调用系统调来刷新

上面我们指的缓冲区是用户级缓冲区,这个缓冲区是C标准库提供的,除此之外,还有内核级缓冲区,其实调用write,也不是直接写到外设上的,而是每个file结构体都有对应的内核缓冲区。

需要注意的是:
1.我们需要避免在全缓冲策略下在还未刷新数据前关闭文件描述符导致数据并未刷新
2.通过关闭1号文件描述符,再让打开的文件取占位,就可以达到行刷新的目的

在这里插入图片描述

相关内容

热门资讯

汽车油箱结构是什么(汽车油箱结... 本篇文章极速百科给大家谈谈汽车油箱结构是什么,以及汽车油箱结构原理图解对应的知识点,希望对各位有所帮...
美国2年期国债收益率上涨15个... 原标题:美国2年期国债收益率上涨15个基点 美国2年期国债收益率上涨15个基...
嵌入式 ADC使用手册完整版 ... 嵌入式 ADC使用手册完整版 (188977万字)💜&#...
重大消息战皇大厅开挂是真的吗... 您好:战皇大厅这款游戏可以开挂,确实是有挂的,需要了解加客服微信【8435338】很多玩家在这款游戏...
盘点十款牵手跑胡子为什么一直... 您好:牵手跑胡子这款游戏可以开挂,确实是有挂的,需要了解加客服微信【8435338】很多玩家在这款游...
senator香烟多少一盒(s... 今天给各位分享senator香烟多少一盒的知识,其中也会对sevebstars香烟进行解释,如果能碰...
终于懂了新荣耀斗牛真的有挂吗... 您好:新荣耀斗牛这款游戏可以开挂,确实是有挂的,需要了解加客服微信8435338】很多玩家在这款游戏...
盘点十款明星麻将到底有没有挂... 您好:明星麻将这款游戏可以开挂,确实是有挂的,需要了解加客服微信【5848499】很多玩家在这款游戏...
总结文章“新道游棋牌有透视挂吗... 您好:新道游棋牌这款游戏可以开挂,确实是有挂的,需要了解加客服微信【7682267】很多玩家在这款游...
终于懂了手机麻将到底有没有挂... 您好:手机麻将这款游戏可以开挂,确实是有挂的,需要了解加客服微信【8435338】很多玩家在这款游戏...