[Linux]基础IO(中)---理解重定向与系统调用dup2的使用、缓冲区的意义

news/2024/9/8 4:23:36/

重定向理解

        在Linux下,当打开一个文件时,进程会遍历文件描述符表,找到当前没有被使用的 最小的一个下标,作为新的文件描述符。

代码验证:

①:先关闭下标为0的文件,在打开一个文件,此时该文件的fd为0

  #include<stdio.h>#include<sys/types.h>#include<fcntl.h>#include<string.h>#include<unistd.h>int main(){//提前关闭下标为0的文件close(0);int fd=open("log.txt",O_WRONLY|O_CREAT|O_TRUNC,0666);if(fd<0){perror("open");return 1;}printf("log.txt打开成功:fd:%d\n",fd);                                                                                                                                                       close(fd);return 0;}

②:关闭下标为1的文件,在打开一个新的文件,再用 printf 打印一段信息

  #include<stdio.h>#include<sys/types.h>#include<fcntl.h>#include<string.h>#include<unistd.h>int main(){//提前关闭下标为1的文件close(1);int fd=open("log.txt",O_WRONLY|O_CREAT|O_TRUNC,0666);if(fd<0){perror("open");return 1;}printf("log.txt打开成功:fd:%d\n",fd);fflush(stdout);                                                                                                                                                       close(fd);return 0;}

出现的问题:

1.printf输出的内容没有出现在显示器上

2.应该在显示器上出现的信息却被加载到了文件中

【解释】:

在上述代码中,我们先关闭了下标为1的文件,在操作系统中该文件对应的是标准输出(显示器),而我们打开文件后,会将下标1作为该文件的描述符,printf函数的作用就是向下标为1的文件中写入信息,但是此时下标1对应的不在是标准输出了,对应的是我们打开的文件,但是上层仍认为1号下标对应的就是显示器,所以向1号下标文件写入就相当于向文件写入,而这个现象就称之为重定向,其本质是在内核中改变文件描述符表特定下标的内容,与上层无关

系统调用函数 dup2

该函数的功能是将文件描述符oldfd所对应文件内容拷贝给newfd对应文件

#include <unistd.h>
int dup2(int oldfd, int newfd);

举例:

  #include<stdio.h>#include<sys/types.h>#include<fcntl.h>#include<string.h>#include<unistd.h>int main(){int fd=open("log.txt",O_WRONLY|O_CREAT|O_TRUNC,0666);if(fd<0){perror("open");return 1;}dup2(fd,1);printf("hello Linux\n");printf("hello Linux\n");printf("hello Linux\n");                                                                                                                                                                   fflush(stdout);close(fd);return 0;}

缓冲区理解

如果将上述代码中的 fflush(stdout) 删除的话,应该向文件写入的信息又写不进去了,这又是为什么呢?程序结束不是会自动刷新缓冲区吗?信息去哪里了?

【解释】:

在c语言中,为了用户使用方便,封装了三个结构体,stdout、stdin、stderr,这三个结构体中除了封装了文件描述符外,还存在着语言级别的文件缓冲区

在[Linux]基础IO(上)--理解文件系统调用、文件描述符、万物皆文件一文中我们谈到,每一个文件的struct file都存在一个内核级的文件缓冲区,printf输出的内容会先保存在语言级别的那个缓冲区中,C语言在通过文件描述符将该缓冲区的内容加载到内核级别的文件缓冲区中,操作系统在刷新到外设

此时,程序中printf输出的内容就保存在语言级别的文件缓冲区中,虽然程序结束时会自动刷新缓冲区,但是在程序结束前,我们就已经将文件关闭了,就无法向文件中写入信息了,当程序结束时,这部分数据就丢失了

缓冲区刷新策略

1.立即刷新:fflush(stdout)  int fsync(int fd) 

2.行刷新:写满一行就刷新(显示屏)

3.全刷新:当缓冲区写满才刷新

4.特殊情况:程序结束强制刷新

缓冲区的意义:
  •  解耦:对于语言级别的文件缓冲区,只需要想怎样将数据导入缓冲中,不需要管语言怎么再将数据导入内核级文件缓冲区,对于内核级文件缓冲区,将数据导入进来后,就不需要管操作系统怎样将数据刷新到外设中了
  • 提高效率:系统调用是有一定的成本的,当缓冲区写满或者写完一行时,再调用系统接口,一次或多次的将内容进行处理,这样可以极大减少系统调用的次数,不仅可以提高IO速率,也可以提高用户的使用效率

http://www.ppmy.cn/news/1404977.html

相关文章

合并两个单链表

归纳编程学习的感悟&#xff0c; 记录奋斗路上的点滴&#xff0c; 希望能帮到一样刻苦的你&#xff01; 如有不足欢迎指正&#xff01; 共同学习交流&#xff01; &#x1f30e;欢迎各位→点赞 &#x1f44d; 收藏⭐ 留言​&#x1f4dd; 但行前路&#xff0c;不负韶华&#…

探析Drools规则引擎的工作机制

目录 一、工作原理 二、工作流程 2.1 初始化环境 2.2 添加规则文件 2.3 编译规则文件 2.4 插入到工作内存 2.5 规则匹配与激活 2.6 规则执行 三、Drools 其他特性 3.1 符合事实 3.2 决策表 3.3 规则生命周期管理 3.4 规则流 四、Rete 算法 一、工作原理 Drools 规则引擎的工…

谷歌(Google)技术面试——在线评估问题(一)

谷歌&#xff08;Google&#xff09;面试过程的第一步&#xff0c;你可能会收到一个在线评估链接。 评估有效期为 7 天&#xff0c;包含两个编码问题&#xff0c;需要在一小时内完成。 以下是一些供你练习的在线评估问题。 在本章结尾处&#xff0c;还提供了有关 Google 面试不…

最新AI工具系统ChatGPT网站运营源码SparkAi系统V6.0版本,GPTs应用、AI绘画、AI换脸、垫图混图、Suno-v3-AI音乐生成大模型全支持

一、前言 SparkAi创作系统是基于ChatGPT进行开发的Ai智能问答系统和Midjourney绘画系统&#xff0c;支持OpenAI-GPT全模型国内AI全模型。本期针对源码系统整体测试下来非常完美&#xff0c;那么如何搭建部署AI创作ChatGPT&#xff1f;小编这里写一个详细图文教程吧。已支持GPT…

酷开科技智慧AI让酷开系统大显身手!

时代的浪潮汹涌而至&#xff0c;人工智能作为技术革新和产业变革的重要引擎&#xff0c;正深刻地影响着各行各业。在科技的海洋中&#xff0c;AI技术正逐渐渗透到我们的日常生活中&#xff0c;为我们带来前所未有的便捷和智慧。酷开科技用技术探索智慧AI&#xff0c;别看它只是…

微服务(基础篇-007-RabbitMQ部署指南)

目录 05-RabbitMQ快速入门--介绍和安装_哔哩哔哩_bilibilihttps://www.bilibili.com/video/BV1LQ4y127n4?p65&vd_source60a35a11f813c6dff0b76089e5e138cc 1.单机部署 1.1.下载镜像 1.2.安装MQ 2.集群部署 2.1.集群分类 2.2.设置网络 视频地址&#xff1a; 05-Rab…

达梦数据库用户与权限管理

达梦数据库用户与权限管理 用户管理口令策略管理用户资源限制 权限管理一般权限特殊权限 角色管理 用户管理 达梦数据库安装后创建的内置用户&#xff1a; SYS&#xff1a;内置用户&#xff0c;不允许登录。该用户下有常用的数据字典&#xff1b;SYSDBA&#xff1a;系统管理员…

Linux(05) Debian 系统修改主机名

查看主机名 方法1&#xff1a;hostname hostname 方法2&#xff1a;cat etc/hostname cat /etc/hostname 如果在创建Linux系统的时候忘记修改主机名&#xff0c;可以采用以下的方式来修改主机名称。 修改主机名 注意&#xff0c;在linux中下划线“_”可能是无效的字符&…

elment UI el-date-picker 月份组件选定后提交后台页面显示正常,提交后台字段变成时区格式

需求&#xff1a;要实现一个日期的月份选择<el-date-picker :typeformData.dateType :value-formatdateFormat v-modelformData.leaveFactoryDateplaceholder选择月份></el-date-picker>错误示例&#xff1a;将日期显示类型(type)dateType或将日期绑定值的格式(val…

Linux网络编程一(协议、TCP协议、UDP、socket编程、TCP服务器端及客户端)

文章目录 协议1、分层模型结构2、网络应用程序设计模式3、ARP协议4、IP协议5、UDP协议6、TCP协议 Socket编程1、网络套接字(socket)2、网络字节序3、IP地址转换4、一系列函数5、TCP通信流程分析 第二次更新&#xff0c;自己再重新梳理一遍… 协议 协议&#xff1a;指一组规则&…

Android Studio学习7——常用控件view

Android控件 双击shift键——>搜索想要找的文件 Ctrlshift回车——>补全“&#xff1b;”号 CtrlX——>删除一行&#xff0c;只需把鼠标放在那一行 windows自带字体

深入探索Linux的lsof命令

在Linux系统中&#xff0c;了解哪些文件被哪些进程打开对于系统管理和问题诊断是极其重要的。这正是lsof命令&#xff0c;即List Open Files&#xff0c;发挥其强大功能的场景。本文旨在详细介绍lsof的起源、底层原理、参数意义&#xff0c;常见用法&#xff0c;并详解其返回结…

Hive初始化元数据库(默认是derby数据库)时候出现缺少方法的错误com.google.common.base.Preconditions

错误的出现&#xff1a; 下载好hive后&#xff0c;初始化元数据库&#xff08;使用内置derby数据测试&#xff09;&#xff0c;出现报错 初始化hive元数据&#xff1a;schematool -dbType derby -initSchema 这个原因是与 Hive 和 Hadoop 版本的 Guava 版本不一样导致的。 解决…

CSS层叠样式表学习(2)

&#xff08;大家好&#xff0c;今天我们将继续来学习CSS&#xff08;2&#xff09;的相关知识&#xff0c;大家可以在评论区进行互动答疑哦~加油&#xff01;&#x1f495;&#xff09; 目录 二、CSS基础选择器 2.1 CSS选择器的作用 2.2 选择器分类 2.3 标签选择器 2.…

动态规划(Dynamic Programming)详解

动态规划&#xff08;Dynamic Programming&#xff0c;简称DP&#xff09;就像是个聪明的厨师&#xff0c;他懂得怎样把一道复杂的菜肴分成一小块一小块来做&#xff0c;而且他知道怎么利用之前做好的部分&#xff0c;避免重复劳动&#xff0c;最后拼凑成美味佳肴。 比如&…

Debian 配置国内软件源

为什么需要&#xff1f; Debian安装好之后默认是没有软件源的&#xff0c;只能通过本身的光盘上的软件进行安装&#xff0c;这样明显是不能够满足我们的需要的&#xff0c;考虑到国内的上网速度以及环境&#xff0c;配置一个国内的阿里镜像源是最好的选择。 使用 sudo vim /…

更高效、更简洁的 SQL 语句编写丨DolphinDB 基于宏变量的元编程模式详解

元编程&#xff08;Metaprogramming&#xff09;指在程序运行时操作或者创建程序的一种编程技术&#xff0c;简而言之就是使用代码编写代码。通过元编程将原本静态的代码通过动态的脚本生成&#xff0c;使程序员可以创建更加灵活的代码以提升编程效率。 在 DolphinDB 中&#…

Python中主要数据结构的使用

文章目录 数组队列 queue双端队列 deque栈 stack优先队列 priority_queue集合 set映射/字典 map 数组 使用内置类型list实现&#xff0c;主要有如下操作&#xff1a; array [] array.append(1) length len(array) if not array:# 列表为空print("array is empty"…

QT使用数据库和proC数据库

一&#xff0c;QT使用数据库 数据库就是保存数据的文件。可以存储大量数据&#xff0c;包括插入数据、更新数据、截取数据等。用专业术语来说&#xff0c;数据库是“按照数据结构来组织、存储和管理数据的仓库”。 什么时候需要数据库&#xff1f;在嵌入式里&#xff0…

Zookeeper脑裂解决方案

Zookeeper脑裂原因&#xff1a; 主要原因是Zookeeper集群和Zookeeper client判断超时并不能做到完全同步&#xff0c;也就是说可能一前一后&#xff0c;如果是集群先于client发现&#xff0c;那就会出现上面的情况。同时&#xff0c;在发现并切换后通知各个客户端也有先后快慢…