当前位置: 首页 > news >正文

Linux 基础IO 二

1.文件描述符的分配规则

#include<stdio.h>
#include<string.h>
//#include<unistd.h>
#include<sys/types.h>
#include<sys/stat.h>
#include<fcntl.h>int main()
{close(1);//fd分配原则,从最小的开始,没有被占用的文件描述符给新打开的文件;int fd = open("log.txt", O_CREAT | O_TRUNC | O_RDONLY, 0666);if (fd < 0){perror("open");return 1;}//按道理,都应该是往显示器(标准输出)打印的;//但是下面的都写入到了log.txt中;//这叫什么呢?输出重定向;printf("fd:%d\n", fd);//stdout在FILE中的fd=1;而printf只向1中打印,他不管1到底是谁;1原本指向的是stdout,现在成了log.txt;fprintf(stdout, "hello printf\n");const char* s = "hello fwrite\n";fwrite(s, strlen(s), 1, stdout);return 0;
}

1.1输出重定向原理:文件操作前,进程会默认关联打开三个文件标准流文件;可是已经关闭了标准输出流,相当于把files_struct arrary指针数组中的'1'位置的数据置为了NULL;可是上层面已经把stdout 设置成了‘1’;根据文件描述符分配规则;所以就写入了log.txt;

重定向的本质,其实就是在OS内部,更改fd对应的内容的指向;

1.2输入重定向

#include<stdio.h>
#include<string.h>
//#include<unistd.h>
#include<sys/types.h>
#include<sys/stat.h>
#include<fcntl.h>int main()
{close(0);int fd = open("log.txt", O_RDONLY);if (fd < 0){perror("open");return 1;}printf("fd:%d\n");char buffer[64];fgets(buffer, sizeof(buffer), stdin);printf("%s\n", buffer);return 0;
}

1.3追加重定向

#include<stdio.h>
#include<string.h>
//#include<unistd.h>
#include<sys/types.h>
#include<sys/stat.h>
#include<fcntl.h>int main()
{close(1);int fd = open("log.txt", O_APPEND |O_WRONLY |O_CREAT);if (fd < 0){perror("open");return 1;}fprintf(stdout,"you can see me sucessly\n");return 0;
}

2.以上全是野路子,是为了理解基本原理来写的;具体的看以下:

函数int  dup(int oldfd,int newfd)  :1:newfd  3:oldfd

#include<stdio.h>
#include<string.h>
//#include<unistd.h>
#include<sys/types.h>
#include<sys/stat.h>
#include<fcntl.h>int main(int argc,char* argv[])
{if (argc != 2) return 2;int fd = open("log.txt", O_CREAT |O_WRONLY |O_CREAT);if (fd < 0){perror("open");return 1;}fprintf(stdout,"%s\n",argv[1]);//stdout ->1->显示器dup2(fd, 1);  //重定向fprintf(stdout, "%s\n", argv[1]);close(fd)return 0;
}

3. 底层不同的硬件,一定对应着不同的操作方法。

但是不同的硬件都是外设,每一个设备的核心的访问函数都可以是  read  、write  (I/O)

所以:所有的设备,都有自己的read、write 但是代码的实现都不一样,就形成了类似C++的多态,调的函数名相同,但调用的不同——这样就是Linux下的一切皆文件——>VFS (virtual file system)虚拟文件系统

4.缓冲区问题

4.1什么是缓冲区? 答:就是一段内存空间

4.2为什么要有缓冲区?答:为了提高效率。如果cpu想向外设发送数据,肯定会等待多条数据一同发送到同一个外设中,而不是多次发送,所以提高了效率;主要是为了提高用户的响应速度;(写回模式)cpu太快了,相比之下磁盘太慢了,cpu等不起磁盘写入;

4.3缓冲区在哪里?谁提供?  答:

4.4缓冲区的发送数据的策率?答: 1.立即刷新  2.行刷新 (行缓冲,一般以\r,\n)3.满刷新(全缓冲:必须把缓冲区写满了,就刷新) 4.特殊情况:1.用户强制刷新(fflush) 2.进程退出,也会强制刷新;

4.5关于缓冲区的认知

一般而言,行缓冲的设备文件——是显示器

全缓冲的设备文件——磁盘文件

所有的设备,永远都倾向于全缓冲!因为缓冲区满了才刷新,意味着需要更少次的I/O操作——>更少的外设访问成本(提高效率)——cpu、内存和外设I/O的时候,数据量的大小不是主要矛盾,和外设预备I/O的过程才是最耗费时间的;其他的刷新策略,都是结合实际情况做的妥协;

显示器:是直接给用户看的,一方面要照顾效率,一方面要照顾用户体验;

极端情况下:是可以自定义规则的;

5.同样一个程序,向显示器打印输出4行文字,向普通文件(磁盘文件)打印输出7行,其中C的I/O接口打印了两次,系统接口打印了1次,和向显示器打印一样;

#include<stdio.h>
#include<string.h>
//#include<unistd.h>
#include<sys/types.h>
#include<sys/stat.h>
#include<fcntl.h>int main()
{//C语言提供的fprintf(stdout, "hello fprintf\n");printf("hello printf\n");const char* s = "hello fputs\n";fputs(s, stdout);//OS提供的const char* ss = "hello write\n";write(1, ss, strlen(ss));//注意我是在最后才调用的fork,上面的函数已经跑完了fork();//创建子进程;return 0;
}

问题1:上面的测试,并不能影响系统接口!

问题迁移:上述代码用到了几个知识? 答:写时拷贝技术,将缓冲区的数据考了一份给子进程;显示器和磁盘的刷新策略不同;文件输出重定向;————对程序进行了重定向,隐形的刷新策略变成了全缓冲,\n无意义了,fork的时候,函数已经执行完了,但是数据还未刷新,父进程里的缓冲区的数据,会被子进程接收,fork之后,父子分流,之后return,父子各自退出;进程退出,强行刷新;刷新是将缓冲区数据刷给内存,也是写时拷贝(不仅仅是改变变量数据)给子进程,所以打印了两份

如果有所谓的缓冲区,我们之前所谈的缓冲区,绝对不是由操作系统提供的,应该是由C标准库维护的,也就所谓的语言层面维护的;

5.1缓冲区在哪?答:进程启动连接了C标准库,缓冲区就是C标准库中开辟的一段内存空间,fputs数据,就是把数据写入到了这段内存空间中,在由标准库调用系统接口,压入磁盘;

5.2以上说的缓冲区是C标准库给我们提供的用户级缓冲区;也就是还存在内核级缓冲区;file结构体中也是存在内核缓冲区的,一旦使用write写入内核缓冲区,就代表和进程无关了;

5.3结构体file对象中,不止由fd,还有与缓冲区相关的类型指针

6.实战:自己设计用户缓冲区,minishell支持重定向;

#include<stdio.h>
#include<string.h>
//#include<unistd.h>
#include<sys/types.h>
#include<sys/stat.h>
#include<fcntl.h>
#include<assert.h>
#include<stdlib.h>struct my_file
{int fd;int end;  //当前缓冲区的结尾;char buffer[1024];
};
typedef struct my_file my_file;my_file* fopen_(const char* pathname, const char* mode) 
{assert(pathname);assert(mode);my_file* fp = NULL;if (strcmp(mode, "r") == 0)//C语言用的穷举,C++直接map,里面放lamda就行;{}else if (strcmp(mode, "w") == 0){int fd = open(pathname, O_WRONLY | O_TRUNC | O_CREAT,0666);if (fd >= 0){fp = (my_file*)malloc(sizeof(my_file));memset(fp, 0, sizeof(my_file));fp->fd = fd;}}return fp;
}
void fputs_(const char* message, my_file* fp)//这个接口是由C标准库来执行
{assert(message);assert(fp);strcpy(fp->buffer + fp->end, message);fp->end += strlen(message);//刷新策略;是用户通过执行C标准库中的代码逻辑,来完成刷新;//这里效率提高,体现在哪里?因为C提供了缓冲区,那么我们减少了IO的执行次数if (fp->fd == 0){//标准输入}else if (fp->fd == 1){//标准输出if (fp->buffer[fp->end - 1] == '\n'){write(fp->fd, fp->buffer, fp->end);fp->end = 0;}}else if (fp->fd == 2){//标准错误}else{//其他文件}
}
void fclose_(my_file* fp)
{assert(fp);fflush_(fp);close(fp->fd);free(fp);
}
void fflush_(my_file* fp)
{assert(fp);if (fp->end != 0){//暂且认为刷新——其实是把数据写到了内核write(fp->fd, fp->buffer, fp->end);syncfs(fp->fd);//将数据写入磁盘fp->end = 0;}}int main()
{my_file* fp = fopen_("./log.txt,", "w");if (fp == NULL){printf("open file error");return 1;}fputs_("hello world", fp);fclose_(fp);return 0;
}

相关文章:

Linux 基础IO 二

1.文件描述符的分配规则 #include<stdio.h> #include<string.h> //#include<unistd.h> #include<sys/types.h> #include<sys/stat.h> #include<fcntl.h>int main() {close(1);//fd分配原则&#xff0c;从最小的开始&#xff0c;没有被占用…...

找工作小项目:day15-macOS支持、完善逻辑

macOS支持、完善逻辑 目前的代码可以在Linux上完美运行编译&#xff0c;在Windows上也可以通过WSL编译运行源代码&#xff0c;但是在MacBook上却无法运行编译&#xff0c;这主要是由于macOS上没有epoll&#xff0c;取而代之的很相似的kqueue。由于操作系统不同&#xff0c;我们…...

植物大战僵尸杂交版 v2.0.88 mac版 Plants vs. Zombies 杂交版下载

特别注意&#xff1a;该游戏最低系统要求为macOS Sonoma 14.X&#xff0c;低于此系统版本的请勿下载&#xff01; 游戏介绍 植物大战僵尸杂交版是由B站UP主“潜艇伟伟迷”制作的一款结合了《植物大战僵尸》原有元素与创新玩法的游戏。这款游戏以其独特的“杂交”植物概念在B站…...

PHP中的while循环:用法、技巧与最佳实践

在PHP编程中&#xff0c;while循环是一种基本且常用的控制结构&#xff0c;用于重复执行代码块&#xff0c;直到指定条件为假。while循环在处理未知迭代次数的任务时特别有用&#xff0c;例如读取文件内容、处理用户输入或动态生成数据等。与for循环不同&#xff0c;while循环适…...

如何解决跨境传输常见的安全及效率问题?

在当今全球化的商业版图中&#xff0c;企业为了拓展国际市场和增强竞争力&#xff0c;跨境传输数据已成为一项不可或缺的业务活动。合格的数据跨境传输方案&#xff0c;应考虑以下要素&#xff1a; 法律合规性&#xff1a;确保方案符合所有相关国家的数据保护法律和国际法规&am…...

『大模型笔记』主成分分析(PCA)解释:简化机器学习中的复杂数据!

主成分分析(PCA)解释:简化机器学习中的复杂数据 文章目录 一. 主成分分析(PCA)解释:简化机器学习中的复杂数据!二. 参考文献一. 主成分分析(PCA)解释:简化机器学习中的复杂数据! 主成分分析(Principal Component Analysis,简称PCA)通过 将大型数据集中的维度减少…...

springboot与flowable(5):任务分配(表达式)

在做流程定义时我们需要给相关的用户节点指派对应的处理人。在flowable中提供了三种分配的方式。 一、固定分配 在分配用户时选择固定值选项确认即可。 二、表达式 1、值表达式 2、方法表达式 三、表达式流程图测试 1、导出并部署 导出流程图&#xff0c;复制到项目中 部署流…...

如何使用CCS9.3打开CCS3.0工程

如何使用CCS9.3打开CCS3.0工程 点菜单栏上的project&#xff0c;选择Import Legacy CCSv3.3 Porjects…&#xff0c;弹出对话框&#xff0c;通过Browse…按钮导入一个3.3版本的工程项目&#xff1b; 选择.pjt文件&#xff0c;选择Copy projects into worlkspace 右击选择P…...

Stable Diffusion 3 Medium 模型

开源SD3&#xff0c;中型版本&#xff0c;20亿参数&#xff0c;Stable Diffusion 3 Medium&#xff0c;系统内存要求32G&#xff0c;显卡6G。 a female character with long, flowing hair that appears to be made of ethereal, swirling patterns resembling the Northern Li…...

数据分析------统计学知识点(五)

回归算法 想象一下&#xff0c;你和朋友在讨论:大学生活中&#xff0c;每天学习的时间是否真的能影响期末成绩?这个问题看似简单&#xff0c;实则包含了一个潜在的关系:学习时间与成绩之间的联系。我们想要知道&#xff0c;增加学习时间是否会提高成绩&#xff0c;以及这种提…...

Superset二次开发之Git篇 git remote

背景:从GitHub clone Superset项目,基于3.0版本做二次开发,后续通过其他方式把3.0版本未做任何修改过的原始代码上传到企业GitLab库develop分支 任务:本地代码推送到GitLab库develop分支,但是两者似乎没有任何关联关系 操作步骤 克隆 Superset 3.0 版本的项目到本地: …...

记录一下PHP使用微信小程序支付

记录一下PHP使用微信小程序支付V3版本经历 官方文档&#xff1a;https://pay.weixin.qq.com/wiki/doc/apiv3/open/pay/chapter2_8_0.shtml 请详细查看文档中小程序支付接入前准备&#xff08;https://pay.weixin.qq.com/wiki/doc/apiv3/open/pay/chapter2_8_1.shtml&#xff…...

【数据结构初阶】 --- 单链表

关于链表你应该先了解这些 下图描述了物理模型和逻辑模型&#xff0c;大多数常见的其实是逻辑模型&#xff0c;但这对初学者或者掌握不扎实的同学不太友好&#xff0c;所以这里我重点讲解物理模型&#xff0c;当了解了这些细节&#xff0c;以后做题或是什么就直接画逻辑模型就…...

并发、多线程、HTTP连接数有何关系?

在计算机领域&#xff0c;"并发"、"多线程"和"HTTP连接数"是三个重要的概念&#xff0c;它们之间存在着密切的关系。本文将探讨这三者之间的联系以及它们在现代计算机系统中的作用。 一、并发的概念 并发是指系统能够同时处理多个任务或事件的能…...

鸿蒙轻内核Kconfig使用笔记

鸿蒙轻内核使用Kconfig进行图形化配置&#xff0c;本文专门讲解下鸿蒙轻内核LiteOS-M和LiteOS-A的图形化配置方法。本文中所涉及的源码&#xff0c;均可以在开源站点 https://gitee.com/openharmony/kernel_liteos_a 、 https://gitee.com/openharmony/kernel_liteos_m 获取。本…...

react 0至1 案例

/*** 导航 Tab 的渲染和操作** 1. 渲染导航 Tab 和高亮* 2. 评论列表排序* 最热 > 喜欢数量降序* 最新 > 创建时间降序* 1.点击记录当前type* 2.通过记录type和当前list中的type 匹配*/ import ./App.scss import avatar from ./images/bozai.png import {useState} …...

基于MCU平台的HMI开发的性能优化与实战(上)

随着汽车座舱智能化的不断演进&#xff0c;车内显示设备的数量显著增加&#xff0c;从传统的仪表盘和中控屏扩展至空调控制、扶手、副驾驶区域以及抬头显示&#xff08;HUD&#xff09;等多样化的显示单元。为了有效支持这些功能单元&#xff0c;同时控制整车成本&#xff0c;越…...

【Tkinter界面】Canvas 图形绘制(02/5)

文章目录 一、说明二、几何时使用 Canvas 组件2.1 用法2.2 简单范例2.3 对象移动2.4 对象删除2.5 文字对象显示 三、画布和画布对象3.1 画布生成函数原型3.2 使用create_xxx()方法3.3 对参数**options的解释 一、说明 Canvas&#xff08;画布&#xff09;组件为 Tkinter 的图形…...

1_常见指令【Linux中常见30个指令的学习和使用】【万字长文】

常见指令以及权限理解 开始学习linux前的注意事项 在学习linux之前&#xff0c;我们要知道linux是一个操作系统。 那操作系统是什么呢&#xff1f;&#xff08;这里只做大概了解&#xff09; 操作系统就是一个管理软硬件的软件。 它对上提供良好&#xff08;稳定、高效、安…...

每日复盘-202406014

今日关注: 这几天市场打板情绪环境转好,轻仓试错 20240614 六日涨幅最大: ------1--------301036--------- 双乐股份 五日涨幅最大: ------1--------301036--------- 双乐股份 四日涨幅最大: ------1--------301036--------- 双乐股份 三日涨幅最大: ------1--------301082-…...

用docker来安装部署freeswitch记录

今天刚才测试一个callcenter的项目&#xff0c;所以尝试安装freeswitch 1、使用轩辕镜像 - 中国开发者首选的专业 Docker 镜像加速服务平台 编辑下面/etc/docker/daemon.json文件为 {"registry-mirrors": ["https://docker.xuanyuan.me"] }同时可以进入轩…...

Unity | AmplifyShaderEditor插件基础(第七集:平面波动shader)

目录 一、&#x1f44b;&#x1f3fb;前言 二、&#x1f608;sinx波动的基本原理 三、&#x1f608;波动起来 1.sinx节点介绍 2.vertexPosition 3.集成Vector3 a.节点Append b.连起来 4.波动起来 a.波动的原理 b.时间节点 c.sinx的处理 四、&#x1f30a;波动优化…...

以光量子为例,详解量子获取方式

光量子技术获取量子比特可在室温下进行。该方式有望通过与名为硅光子学&#xff08;silicon photonics&#xff09;的光波导&#xff08;optical waveguide&#xff09;芯片制造技术和光纤等光通信技术相结合来实现量子计算机。量子力学中&#xff0c;光既是波又是粒子。光子本…...

群晖NAS如何在虚拟机创建飞牛NAS

套件中心下载安装Virtual Machine Manager 创建虚拟机 配置虚拟机 飞牛官网下载 https://iso.liveupdate.fnnas.com/x86_64/trim/fnos-0.9.2-863.iso 群晖NAS如何在虚拟机创建飞牛NAS - 个人信息分享...

离线语音识别方案分析

随着人工智能技术的不断发展&#xff0c;语音识别技术也得到了广泛的应用&#xff0c;从智能家居到车载系统&#xff0c;语音识别正在改变我们与设备的交互方式。尤其是离线语音识别&#xff0c;由于其在没有网络连接的情况下仍然能提供稳定、准确的语音处理能力&#xff0c;广…...

Ubuntu系统多网卡多相机IP设置方法

目录 1、硬件情况 2、如何设置网卡和相机IP 2.1 万兆网卡连接交换机&#xff0c;交换机再连相机 2.1.1 网卡设置 2.1.2 相机设置 2.3 万兆网卡直连相机 1、硬件情况 2个网卡n个相机 电脑系统信息&#xff0c;系统版本&#xff1a;Ubuntu22.04.5 LTS&#xff1b;内核版本…...

软件工程 期末复习

瀑布模型&#xff1a;计划 螺旋模型&#xff1a;风险低 原型模型: 用户反馈 喷泉模型:代码复用 高内聚 低耦合&#xff1a;模块内部功能紧密 模块之间依赖程度小 高内聚&#xff1a;指的是一个模块内部的功能应该紧密相关。换句话说&#xff0c;一个模块应当只实现单一的功能…...

CSS3相关知识点

CSS3相关知识点 CSS3私有前缀私有前缀私有前缀存在的意义常见浏览器的私有前缀 CSS3基本语法CSS3 新增长度单位CSS3 新增颜色设置方式CSS3 新增选择器CSS3 新增盒模型相关属性box-sizing 怪异盒模型resize调整盒子大小box-shadow 盒子阴影opacity 不透明度 CSS3 新增背景属性ba…...

归并排序:分治思想的高效排序

目录 基本原理 流程图解 实现方法 递归实现 非递归实现 演示过程 时间复杂度 基本原理 归并排序(Merge Sort)是一种基于分治思想的排序算法&#xff0c;由约翰冯诺伊曼在1945年提出。其核心思想包括&#xff1a; 分割(Divide)&#xff1a;将待排序数组递归地分成两个子…...

Netty自定义协议解析

目录 自定义协议设计 实现消息解码器 实现消息编码器 自定义消息对象 配置ChannelPipeline Netty提供了强大的编解码器抽象基类,这些基类能够帮助开发者快速实现自定义协议的解析。 自定义协议设计 在实现自定义协议解析之前,需要明确协议的具体格式。例如,一个简单的…...