Linux-- 重定向缓冲区

目录

0.接上篇文章

1.粗略的见一下这两个问题

2.理解重定向 

3.理解缓冲区 


0.接上篇文章

Linux--基础IO(文件描述符fd)-CSDN博客

1.粗略的见一下这两个问题

先来了解几个函数:

         stat()函数用于获取指定文件或符号链接的元数据。如果文件是一个符号链接,stat()将返回该符号链接本身的元数据,而不是它所指向的目标文件的元数据。

   fstat()函数用于获取已打开文件的元数据。它通常用于在文件描述符已经打开之后获取文件的元数据。

   lstat()函数与stat()函数类似,但它专门用于获取符号链接的元数据。如果指定的文件是一个符号链接,lstat()将返回该符号链接本身的元数据,而不是它所指向的目标文件的元数据。

  • fd:一个已打开的文件描述符。
  • buf:一个指向struct stat的指针,用于存储符号链接的元数据。
  • path:要检查的文件或目录的路径。

        这三个函数都使用struct stat结构来存储文件的元数据。这个结构包含了许多字段,如文件类型(普通文件、目录、符号链接等)、权限、所有者ID、组ID、大小、时间戳等。具体的字段取决于你的系统和编译器,但你可以查阅sys/stat.h头文件以获取更多详细信息。

演示:


再来看一段代码:

        我们打开文件的时候做了一个操作,colse(1)首先关闭了文件描述符 1,我们知道文件描述符1,表示的是显示器文件,而printf&&fprintf都是向显示器上打印的,现在关闭了显示器文件,意味着显示器上不会出现打印的内容。

        文件描述符1被关闭了,意味着fd1空了出来,那么log.txt将继承fd1(文件描述符分配规则;查自己的文件描述表,分配最小的没有被使用的fd),那么现在向fd1中写就是在向log.txt中写,所以我们查看到log.txt中的内容就是printf&&fprintf输出的内容,这就是对文件做重定向重定向的本质:是在内核中改变文件描述符表特定下标的内容,和上层无关!)

在这段代码中:我们还需要注意一点,fflush(stdout)刷新stdout,如果不进行此操作,log.txt中是不会有任何内容的,这是为什么呢?

原因是:在struct FILE*这个结构体中存在语言级别的缓冲区,我们在使用printf&&fprintf时,并不是直接通过文件描述符写入到内核文件缓冲区中,而是先写到语言级别的缓存区中,再由C语言通过文件描述符,刷新到内核文件缓存区当中,此时外设才能看到输出的内容,因此fflush(stdout)此时的工作是将stdout缓冲区中的内容通过文件描述符1,刷新到log.txt内核文件缓存区当中去,这时候log.txt中才能看到内容。如果没有close(fd)这一语句,那么不加刷新也没关系,进程结束之后,会自动通过fd刷新到文件中。


2.理解重定向 

先认识一个系统调用接口:dup2

  dup2 的功能是将一个已存在的文件描述符复制到另一个文件描述符,如果目标文件描述符已经打开,则先将其关闭。(本质是文件描述符下标所对应内容的拷贝)

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

1. 标准输出重定向,由显示器打印->log.txt打印(接上面例子,我们使用dup2系统调用接口该如何做呢?)

        也就是我们没有关闭fd1,那么新打开的log.txt的fd就是3,我们使用了dup2的效果就是,把fd3的内容拷贝给了fd1,也就是说,让fd1指向了文件log.txt,所以未来向fd1里写入内容,实际上就是向log.txt中写入内容,最终只会留下fd3(oldfd)。(fd1和fd3里的地址一样l)

那么代码就应该这么写:

这样输出到显示器的内容就输出到log.txt了


3.理解缓冲区 

在Linux操作系统中,缓冲区是一个非常重要的概念,主要用于提高I/O(输入/输出)操作的效率。以下是关于Linux操作系统中缓冲区的理解:

  1. 概念:缓冲区是内存中的一块区域,用于临时存放数据。当进程需要向外部设备(如磁盘、网络等)写入数据时,它不会直接将数据写入设备,而是先将数据写入到缓冲区中。同样,当进程从外部设备读取数据时,数据也是先从设备读取到缓冲区,当缓冲区的数据到达某个值的时候,在统一的刷新到进程中。
  2. 作用
    • 减少对外部设备的直接访问次数,从而降低I/O操作的开销。
    • 允许进程进行批量数据传输,从而提高数据传输的效率。
    • 通过缓存数据,可以实现对数据的预处理和后处理,如数据压缩、加密等。
  3. 刷新策略:Linux中的缓冲区有不同的刷新策略,以适应不同的应用场景。
    • 无缓冲:数据一写入到缓冲区就立即刷新到外部设备。(eg:1.语言级的缓冲区printf/fprintf,2.系统调用fsync)
    • 行缓冲:当在输入或输出中遇到换行符(\n)时,缓冲区会刷新一次。这种策略常用于与终端设备(如显示器)的交互。
    • 全缓冲:当缓冲区满时,数据才会被刷新到外部设备。这种策略常用于写入磁盘文件等场景。
    • 特殊情况(1.进程退出,自动刷新;2强制刷新)
  4. 与文件系统的关系:在Linux文件系统中,缓冲区也起着重要的作用。当应用程序读取文件时,内核会将文件数据读入内核空间缓冲区中,然后再将数据从内核空间缓冲区复制到用户空间缓冲区中。同样地,当应用程序向文件写入数据时,数据也是先写入到用户空间缓冲区中,然后再由内核将数据从用户空间缓冲区复制到内核空间缓冲区,并最终写入到磁盘上。
  5. 缓冲区就在struct FILE*结构体中,每一个文件都有自己的缓冲区(这是在语言层面的)

补充示例

        刷新策略发生改变,看下面的两段代码:

第一段代码及它的运行结果(我们将打印到屏幕的内容重定向到文件中)

第二段代码及它的运行结果(与第一段代码不同的是,加入了一个fork函数)

问题:为什么加了fork之后,会打印两次内容,fork不是只会继承父进程下面的代码吗?为什么C语言库函数的内容打印了两次,而系统调用的只打印了一次呢?

        首先./mytest这个操作是向显示器文件打印,显示器文件的刷新策略是行缓冲,现在转为向普通文件打印,普通文件的刷新策略是全缓冲,由显示器文件转向普通文件打印,这里刷新策略就发生了改变此时printf/fprintf在执行完之后,缓冲区还没有写满(因为是全缓冲),不做刷新,最后fork的时候就出现了父子进程,fork结束后进程就直接退出了,此时父子进程都要执行刷新,所以就打印了两次内容,而系统调用接口是直接向内核级缓冲区中写的,所以不存在刷新两次的问题了。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.rhkb.cn/news/326346.html

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

巩固学习7

正则表达式 就是用来找到符合模式的字符串&#xff0c;这些模式包括&#xff1a;是什么字符&#xff0c;重复多少次&#xff0c;在什么位置&#xff0c;有哪些额外的约束 找某个字符串 import re text身高:178 体重:168 学号:123456 密码:9527 #在Python中&#xff0c;r前缀用…

时间瑾眼中的IT行业现状与未来趋势

文章目录 技术革新与行业应用IT行业的人才培养与教育人工智能与机器学习的演进数据安全与隐私保护可持续发展与绿色技术社会责任与道德规范 随着技术的不断进步&#xff0c;IT行业已成为推动全球经济和社会发展的关键力量。从云计算、大数据、人工智能到物联网、5G通信和区块链…

【Linux 系统】多线程(生产者消费者模型、线程池、STL+智能指针与线程安全、读者写者问题)-- 详解

一、生产者消费者模型&#xff08;重点&#xff09; 如图&#xff0c;在生活中&#xff0c;学生就是消费者角色&#xff0c;工厂是真正的生产者角色&#xff0c;那么超市是什么呢&#xff1f;为什么需要超市&#xff1f;超市是交易场所。我们的家附近不一定有工厂&#xff0c;而…

C++——缺省参数与重载函数

目录 ​前言 一.缺省参数 1.1缺省参数概念 1.2缺省参数分类 注意事项&#xff1a; 二.函数重载 2.1函数重载概念 2.2c支持函数重载原理——命名修饰 前言 本篇文章主要讲述c中有关于缺少参数与函数重载的相关概念与实例&#xff0c;以下是本人拙见&#xff0c;如有错误…

OpenAI之Whisper实时语音分析转文字

1.安装ffmpeg 2.安装python3.11 3.安装whisper pip install whisper conda环境安装whisper conda install whisper 命令行安装openai-whisper pip install openai-whisper 设置环境变量 4.分析语音并输出(默认使用GPU计算&#xff0c;如果没有安装CUDA,请使用CPU) whisper …

centos7.6安装mysql

博客主页&#xff1a;花果山~程序猿-CSDN博客 文章分栏&#xff1a;MySQL之旅_花果山~程序猿的博客-CSDN博客 关注我一起学习&#xff0c;一起进步&#xff0c;一起探索编程的无限可能吧&#xff01;让我们一起努力&#xff0c;一起成长&#xff01; 目录 1.在网页中寻找mysql…

数字水印 | Arnold 变换的 Python 代码实现(灰度图版)

效果 将彩色图转换为灰度图&#xff0c;并进行 A r n o l d \mathsf{Arnold} Arnold 置乱和还原。 代码 import cv2 import numpy as np from matplotlib import pyplot as pltdef arnold(img, shuffle_times, a, b):r, c, d img.shapeimg img[:, :, 0]p np.zeros((r, c),…

【算法刨析】完全背包

完全背包与01背包的区别 01背包对于一个物品只能选择一次&#xff0c;但是完全背包可以选择任意次&#xff1b; 思路 和01背包类似&#xff0c;01背包我们只需要判断选或不选&#xff0c;完全背包也是如此&#xff0c;不同的是&#xff0c;对于这个物品我们在判断选后在增加一…

参加了深圳线下组织的商业沙龙,收获颇丰

能参加本次商业沙龙也本是一连串的事情导致的&#xff0c;听我慢慢道来&#xff1a; 大概在4.13之前无意收到忘了谁发的短信了&#xff0c;说有个啥AI的报告会&#xff0c;然后我就报名了&#xff1a; 会上大佬还是挺多的&#xff0c;来了好多各界的老板和政府的领导&#xff…

springcloud -nacos实战

一、nacos 功能简介 1.1.什么是Nacos&#xff1f; 官方简介&#xff1a;一个更易于构建云原生应用的动态服务发现(Nacos Discovery )、服务配置(Nacos Config)和服务管理平台。 Nacos的关键特性包括&#xff1a; 服务发现和服务健康监测动态配置服务动态DNS服务服务及其元数…

【投稿优惠|快速见刊】2024年能源资源与材料应用国际学术会议(ICERMA 2024)

全称&#xff1a;【投稿优惠|快速见刊】2024年能源资源与材料应用国际学术会议(ICERMA 2024) 会议网址:http://www.icerma.com 会议时间: 2024/2/29 截稿时间&#xff1a;2024/2/20 会议地点: 长沙 投稿邮箱&#xff1a;icermasub-conf.com 投稿标题&#xff1a;ICERMA 2024Art…

深入理解与应用C++ Vector

1. C Vector 简介与基本使用 C 的 vector 是一个序列容器&#xff0c;用于表示可变大小的数组。它结合了数组的高效元素访问和动态大小调整的灵活性。与静态数组相比&#xff0c;vector 的大小可以根据需要自动调整&#xff0c;这是通过在底层使用动态数组来实现的。当新元素被…

【SAP ABAP学习资料】通过RFC接口上传图片至SAP 图片格式转换 图片大小调整

SAP图片相关&#xff1a; 链接: 【SAP ABAP学习资料】图片上传SAP 链接: 【SAP ABAP学习资料】屏幕图片预览 链接: 【SAP ABAP学习资料】smartforms打印图片&#xff0c;动态打印图片 需求&#xff1a; SAP上传图片只能本地电脑选择图片通过SE78或PERFORM IMPORT_BITMAP_BDS上…

计算机网络-网络层

网络层 网络层的主要任务是实现网络互连&#xff0c;进而实现数据包在各网络之间的传输。 需要解决以下主要问题&#xff1a; 网络层向运输层提供怎样的服务网络层寻址问题路由选择问题 两种服务 IPv4地址概述 IPv4地址就是给因特网上的每一台主机&#xff08;或路由器&…

Cocos 2048从创建到发布上线

一、制作2048小游戏过程 扫描体验2048小游戏 场景搭建&#xff0c;4X4棋盘和基础设置绘制背景板&#xff0c;包含预制体等信息考虑在棋盘中随机出现两个数字方块&#xff0c;数字为2&#xff0c;初始化操作滑动事件部分&#xff0c;让方块移动起来&#xff0c;每滑动一次就生成…

websevere服务器从零搭建到上线(二)|Linux上的五种IO模型

文章目录 阻塞 blocking非阻塞 non-blockingIO复用 IO multiplexing信号驱动 signal-driven异步 asynchronous拓展知识 看过上篇文章英国基本能理解本文五张图的内容websevere服务器从零搭建到上线&#xff08;一&#xff09;&#xff5c;阻塞、非阻塞、同步、异步 本文要能够在…

出差——蓝桥杯十三届2022国赛大学B组真题

问题分析 该题属于枚举类型&#xff0c;遍历所有情况选出符合条件的即可。因为只需要派两个人&#xff0c;因此采用两层循环遍历每一种情况。 AC_Code #include <bits/stdc.h> using namespace std; string str;//选择的两人 bool ok(){if(str.find("A")!-1…

java-Spring-Lombok-讲解-(一文一言)创伤是成熟的途径

高手都在孤独前进-致敬我们不悔的青春 我打算每篇文章下找一下文言警句-说不那天会用上&#x1f601;&#x1f601;&#x1f601;&#x1f601; 每篇一言 创伤是成熟的途径 希望经历过创伤的人,能更好享受当下, 爱自己胜过爱别人呀 目录 &#x1f3bb;Lombok简介 &#…

HTML5 Canvas发光Loading动画特效源码

源码介绍 之前我们分享过很多基于CSS3的Loading动画效果&#xff0c;相信大家都很喜欢。今天我们要来分享一款基于HTML5 Canvas的发光Loading加载动画特效。Loading旋转图标是在canvas画布上绘制的&#xff0c;整个loading动画是发光3D的视觉效果&#xff0c;HTML5非常强大。 …

【SpringBoot整合系列】SpringBoot整合RabbitMQ-消息过期(死信队列和延迟队列)

目录 业务场景传统轮询消息队列完整版 默认情况TTL&#xff08;消息的有效期&#xff09;TTL 的设置有两种不同的方式单条消息过期队列消息过期特殊情况 死信队列概述应用场景产生原因原理图死信交换机死信队列实现一下 延迟队列背景定时任务&#xff1f;延迟队列实现思路代码 …