【linux】基础IO(二)

我们在基础IO(一)主要讲述了fd,一切皆文件,文件的系统调用与语言文件库函数的关系,
今天主要进行对重定向与缓冲区的理解与应用。另外,对系统调用的read进行一下使用。

read的使用:

再使用read之前我们先了解一下
在这里插入图片描述
我们知道 文件 = 内容 + 属性,那么我们无非是对文件的内容或属性进行操作,这三个函数就是对文件的属性进行操作,获取对应的文件信息,可以更精细的控制read系统调用函数。
在这里插入图片描述
此函数是输出型函数,我们就从可以传入的这个结构体中获得需要的信息(我们在这只需要文件大小)。
我们写个代码验证一下
在这里插入图片描述
实验结果:

在这里插入图片描述
故我们就初步了解了这个函数的用法,接下来我们使用read函数。
先来简单看一下read函数的使用方法:
在这里插入图片描述
实验代码:
在这里插入图片描述
注意:read的返回值是返回读入字符的个数。

初步理解重定向与文件缓冲区

今天的硬菜就来了。

我们先来探讨一下fd的分配规则

先关闭标准输入
在这里插入图片描述
实验结果:
在这里插入图片描述


将标准错误关闭的结果:
在这里插入图片描述


将标准输出关闭的结果:
什么都没有打印。
在这里插入图片描述
于是我们得到一个结论:
文件标识符总是从最小的开始分配。

但是我们肯定困惑一个点,为什么关闭了1之后就不会打印了呢?

我们在代码中多加几行(fprintf与ffulsh)。在这里插入图片描述

在这里插入图片描述
我们运行程序还是没有打印,
但是我们在创建的文件中发现了原本打印在显示器中的文件打印到了文件中。这是为什么呢?

而注释掉fflush,log.txt文件中也什么都没有了,这就涉及到了两个知识点

重定向:

在这里插入图片描述
于是我们对重定向有了大概得认识、

缓冲区:

那么FILE内除了_fileno外还有别的吗
答案是还有,还有缓冲区的存在!
在这里插入图片描述
于是我们就可以理解上面的问题了
close(1)后向stdout(1)写入,再fflush,不会打印到显示器而是会打印到新打开的文件中,原因是因为重定向,再刷新语言层的缓冲区。

而如果我们不加fflush就不会刷新是因为,我们的进程在return的时候会先刷新缓冲区等清理工作,而我们在进程return之前先close(1),导致无法向1的内容中写入,缓冲区的内容就会丢失。

再理解重定向与文件缓冲区

重定向

我们上述进行的重定向操作实在是比较粗糙,还要先关闭一个文件再打开一个新的。
那我们不想这样做怎么办?
利用系统调用dup2
在这里插入图片描述
在这里插入图片描述

这个函数就是进行重定向的函数。经过学习我们也知道并不是两个fd之间的拷贝,而是他们指向的内容进行拷贝。

经过man的描述,我们也知道了dup2的使用方法。
那我们进行使用一下
在这里插入图片描述
上述操作进行了重定向,因此是向log.txt中进行写入。
在这里插入图片描述
事实也确实如此。


缓冲区:

我们现在已经知道两个缓冲区

  1. 用户级缓冲区
  2. 内核级缓冲区

那么说了这么久,缓冲区到底有什么存在的意义?

  • 解耦
  • 提高效率

解耦我们暂时先不谈。

主要谈谈第二点:
我们知道,文件的写入读出本质都是拷贝,那么我们多了一个缓冲区,多拷贝一次效率快岂不是在扯淡?

答案并不是:

  1. 他可以提高我们使用者的效率,就像你要送一个物品给你的朋友(你在海南他在东北),你是开车去送还是直接顺丰?答案是我们当然选择直接快递,这样提高了我们的效率
  2. 提高IO效率,我们先输出一个结论,调用系统调用是有成本的,OS这么忙还要配合你,无疑是要加重负担。就像我们寄快递,但是只有你一件快递就要求快递员给你送,还是再多囤一囤再一块送?无疑第二种效率更高

我们总结一下:

缓冲区是什么?

  • 一段内存空间。

为什么存在?

  • 给上层提供良好的IO体验,提高整体效率

怎么做

  • 刷新策略(针对用户层面):

a.

  1. 立即刷新,fflush(stdout),fsync(fd)我们暂时还没有用到,刷新内核缓冲区到硬件
  2. 行刷新,针对显示器
  3. 全缓冲,缓冲区写满才刷新,普通文件。

b.特殊情况

  1. 进程退出
  2. 强制刷新,类似a1

练习

那么我们现在写一段奇怪的代码。
在这里插入图片描述
这段代码的现象显而易见。
在这里插入图片描述
重定向到log.txt
在这里插入图片描述
OK,都没问题


那么我们加一个fork?
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
为什么重定向到普通文件中时printf与fprintf会多打印一次?

我们这里要用到刚刚讲过的知识点,
首先我们知道一切的罪魁祸首一定是fork。
其次我们显示器的刷新策略是行刷新,而普通文件是全缓冲。
在这里插入图片描述

所以我们就知道了这样的原因:由于策略发生改变,fork后,语言层的缓冲区会写时拷贝,因此多打印一次,而内核的缓冲区再执行刷新操作时不会写时拷贝。

注意的细节:

fork对文件缓冲区的影响:
在这里插入图片描述

刷新操作不会发生写时拷贝。

在这里插入图片描述

今日IO分享完毕~

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

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

相关文章

CMakeLists.txt编写简单介绍:CMakeLists.txt同时编译.cpp和.cu

关于CMakeLists.txt的相关介绍,这里不赘诉,本人的出发点是借助于CMakeLists.txt掌握基本的C++构建项目流程,下面是本人根据网络资料以及个人实践掌握的资料。 CMakeList.txt构建C++项目 下图是一个使用CUDA实现hello world的项目,一般来说,一个标准的C++项目包括三个文件…

类的函数成员(三):拷贝构造函数

一.什么是拷贝构造函数? 1.1 概念 同一个类的对象在内存中有完全相同的结构,如果作为一个整体进行复制或称拷贝是完全可行的。这个拷贝过程只需要拷贝数据成员,而函数成员是共用的(只有一份拷贝)。 在建立对象…

Linux 文件相关命令

一、查看文件命令 1)浏览文件less 默认查看文件的前 10 行。 less /etc/services ##功能说明: #1.默认打开首屏内容 #2.按【回车】按行访问 #3.按【空格】按屏访问 #4.【从上向下】搜索用/111,搜索包含111的内容,此时按n继续向下搜&#x…

leetcode.203. 移除链表元素

题目 题意:删除链表中等于给定值 val 的所有节点。 示例 1: 输入:head [1,2,6,3,4,5,6], val 6 输出:[1,2,3,4,5] 示例 2: 输入:head [], val 1 输出:[] 示例 3: 输入&#…

LeetCode 热题 100 | 贪心算法

目录 1 121. 买卖股票的最佳时机 2 55. 跳跃游戏 3 45. 跳跃游戏 II 4 763. 划分字母区间 菜鸟做题,语言是 C 1 121. 买卖股票的最佳时机 解题思路: 维护一个变量 max_pricemax_price 用于存储排在 i 天之后的股票最高价格第 i 天的最高利润 …

【MySQL】:深入解析多表查询(上)

🎥 屿小夏 : 个人主页 🔥个人专栏 : MySQL从入门到进阶 🌄 莫道桑榆晚,为霞尚满天! 文章目录 📑前言一. 多表关系1.1 一对多1.2 多对多1.3 一对一 二. 多表查询概述2.1 概述2.2 分类…

升级一下电脑,CPU换I5-14600K,主板换华硕B760M

刚给自己电脑升级了一下,CPU从 AMD R5 5600X 换成 Intel I5-14600K,主板换成了华硕的 TUF GAMING B760M-PLUS WIFI D4。 因为我现有的两根内存是DDR4的,所有我选了个支持DDR4内存的主板。 我发现用AMD处理器时将系统从Win10升级到Win11后变…

基于SSM的邮票鉴赏系统(有报告)。Javaee项目。ssm项目。

演示视频: 基于SSM的邮票鉴赏系统(有报告)。Javaee项目。ssm项目。 项目介绍: 采用M(model)V(view)C(controller)三层体系结构,通过Spring Spri…

frp内网穿透,让外网可以访问内网

需求 我们的svn部署在内网,用的一直没问题,但是有时候有需求在外网访问svn,进行提交更新等操作,这时候就有了内网穿透这个需求。 当然,我们也可以借助花生壳等软件进行内网穿透,傻瓜化操作,也…

Yarn的安装和使用(2):使用及问题解决

Yarn是JavaScript的依赖管理工具,它与npm类似,但提供了一些额外的性能优化和一致性保证。 Yarn的使用: 初始化项目: yarn init 此命令会引导您创建一个新的package.json文件,用于记录项目的元信息和依赖。 添加依赖&…

如何更新Code::blocks的MinGW

前言 LVGL V9版本更新了很多新特性,其中windows平台部分也进行了优化,如果你是用的是Code::blocks体验LVGL那么在编译时会不通过;因为如果你使用的是 Code::blocks 20.03并且使用内置的MinGW,那么就会因为MinGW版本过低遇到下面所…

c++的学习之路:12、vector(1)

这章主要是根据cplusplus中的文档进行使用Vector,文章末附上测试代码。 目录 一、什么是vector 二、vector的简单使用 三、代码 一、什么是vector 下图是cplusplus的简介,上面一共有六点,如下: 1、vector是表示可变大小数组…

Ant Design Vue table固定列失效问题解决

问题描述:项目中封装好的公共table组件,基于Ant Design Vue table封装;使用中,用到了列固定,但是没生效,找了好久的原因。。。最后是因为外层容器标签导致; 解决方法:如果a-table组件…

Linux: linux常见操作指令

目录 01.ls 指令 02. pwd命令 03. cd 指令 04. touch指令 05.mkdir指令(重要) 06.rmdir指令 && rm 指令(重要) 07.man指令(重要) 07.cp指令(重要) 08.mv指令&#…

理解 SQL 数据添加:从基础到实践

引言: 在现代软件开发中,数据库是不可或缺的一部分。而 SQL 作为结构化查询语言的代表,广泛应用于数据库管理系统中,为我们提供了强大的数据管理和查询能力。 主题: 我们将从基础的 SQL INSERT INTO 语句开始&…

EVM Layer2 主流解决方案

深度解析主流 EVM Layer 2 解决方案:zk Rollups 和 Optimistic Rollups 随着以太坊网络的不断演进和 DeFi 生态系统的迅速增长,以太坊 Layer 2 解决方案日益受到关注。 其中,zk Rollups 和 Optimistic Rollups 作为两种备受瞩目的主流 EVM&…

地质地貌卫星影像集锦(三 矿产资源篇)

1. 元古代沉积岩的抬升 这个地区位于Leigh Creek中部,距离澳大利亚南部的阿德莱德约500km,弗林德斯山脉的北面是Gawler克拉通。弗林德斯山脉是由元古代沉积岩抬升后形成的块体,在其之下的是寒武纪的岩石,它座落在距阿德莱德北…

How to install JDK on mac

文章目录 1. Install JDK on mac2. zshenv, zshrc, zprofile3. 查看java环境变量配置 1. Install JDK on mac Installation of the JDK on macOS 2. zshenv, zshrc, zprofile How Do Zsh Configuration Files Work? 3. 查看java环境变量配置 open Terminal,cd…

HTTP 常见面试题(计算机网络)

HTTP 基本概念 一、HTTP 是什么? HTTP(HyperText Transfer Protocol) :超文本传输协议。 HTTP 是一个在计算机世界里专门在「两点」之间「传输」文字、图片、音频、视频等「超文本」数据的「约定和规范」。 「HTTP 是用于从互联网服务器传输超文本到本…

虚拟机打不开

问题 另一个程序已锁定文件的一部分,进程无法访问 打不开磁盘“G:\centeros\hadoop104kl\hadoop100-cl2.vmdk”或它所依赖的某个快照磁盘。 模块“Disk”启动失败。 未能启动虚拟机。 原因 前一次非正常关闭虚拟机导致.lck 文件是VMWare软件的一种磁盘锁文件&…