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

Linux系统编程-标准I/O与系统I/O的比较

目录

一. 标准I/O与系统I/O

1.1 标准I/O与系统I/O的区别

1、标准I/O

2、系统I/O

3、总结

二. 标准I/O

2.1 标准I/O的缓冲机制

2.1.1 标准I/O的缓冲模式:

缓冲区:

行缓冲模式:

全缓冲模式:

无缓冲模式:

2.1.2 fflush()函数

2.1.3 标准I/O合并系统调用

命令:strace

一. 标准I/O与系统I/O

1.1 标准I/O与系统I/O的区别

文件I/O标准I/O
面向文件描述符fd面向文件流指针FILE*
由linux内核提供,属于系统调用,跨平台可移植性差C标准库提供,跨平台可移植性好
无缓冲区,实时性高,可以用在对硬件的控制上有缓冲区,实现数据缓冲,避免频繁的在用户态和内核态之间切换,提高了效率
可以操作普通文件,也可以操作硬件相关的设备类文件,管道,套接字主要用在对普通文件(-)的读写上,文本文件用的多

1、标准I/O

标准I/O具有缓存机制,可以合并系统调用

2、系统I/O

系统I/O每调用一次都会完成从user态kernel态的切换,实时性高

3、总结

标准I/O与系统I/O的区别在与响应速度(实时性)与吞吐量:

标准I/O的吞吐量大,效率高

系统I/O的实时性强

二. 标准I/O

2.1 标准I/O的缓冲机制

首先,来看一段程序:

这里直观的感受是打印出第一个printf的内容,然后进入死循环,但结果不是这样的:

int main() { printf("before while(1)"); while(1); printf("after while(1)"); return 0; }

结果:直接进入了死循环,没有打印,这是因为终端是行缓模式

2.1.1 标准I/O的缓冲模式:

缓存区的作用:大多情况下是好事---合并系统调用

缓存模式解释设备
行缓冲模式

遇到\n刷新

程序退出时刷新

缓冲区满了刷新

强制刷新

缓冲区大小1024字节(1k)

主要用于人机交互的界面

标准输出(终端)

全缓冲模式

缓冲区满了刷新

文件关闭刷新

程序退出刷新

强制刷新

缓冲区大小4096字节(4k)

主要用于对文件的读写(普通文件)

文件操作

默认(除了终端)

无缓冲模式需要立即输出的内容strderr
缓冲区:

高速设备和低速设备进行交互时,为了匹配低速设备的速率,需要在高速设备和低速设备之间增加一个缓冲区,用于数据缓冲

行缓冲模式:

换行刷新:

int main() { printf("hello world\n");//换行刷新 while(1); return 0; }

结果:

强制刷新:

int main() { printf("hello world");//强制刷新 fflush(stdout); while(1); return 0; }

结果:

满了刷新:

int main() { while(1){ printf("hello world"); usleep(100000); } return 0; }

结果:可知行缓冲的大小是1024字节

程序退出刷新:

int main() { printf("hello world"); return 0; }

结果:

全缓冲模式:

满了刷新:

int main() { FILE *fp = fopen("1.txt", "w"); if(fp == NULL){ perror("fopen():"); return -1; } while(1){ fputs("hello world", fp); usleep(10000); } return 0; }

结果:从这里也可以看出,全缓冲的缓冲区大小是4096字节,是以4096的整数倍增加的

无缓冲模式:

stderr:

int main() { fprintf(stderr,"hello world"); return 0; }

结果:

这里介绍一个强制刷新缓冲区的函数:fflush()

2.1.2 fflush()函数

作用:强制刷新指定流的缓冲区

1、对于输出流而言,调用 fflush() 会强制将给定输出或更新流的用户空间缓冲区中的所

有数据进行写入操作,具体操作是通过该流的底层写入函数来实现的。

2、对于与可寻址文件(例如磁盘文件,但不包括管道或终端)相关的输入流,调用

fflush() 会清除从底层文件中读取但尚未被应用程序使用的任何缓冲数据

3、该流的开启状态未受任何影响。

4、如果流参数为 NULL,则 fflush() 函数会刷新所有打开的输出流。

返回值:成功返回0失败返回-1并且设置error

由于终端是行缓存模式,则上面那段程序可以做以下修改使其打印出内容:

int main() { printf("before while(1)\n"); while(1); printf("after while(1)\n"); return 0; }

结果:

也可以使用fflush来强制刷新缓冲区:

int main() { printf("before while(1)"); fflush(stdout); while(1); printf("after while(1)"); fflush(NULL); return 0; }

结果:

2.1.3 标准I/O合并系统调用

这里可以通过一个程序来说明标准I/O缓冲区合并系统调用的作用:

代码:可能打印出ababab

int main() { putchar('a'); write(1, "b", 1); putchar('a'); write(1, "b", 1); putchar('a'); write(1, "b", 1); return 0; }

结果:

命令:strace

这里介绍一个命令:strace + 可执行文件:用来看一个可执行文件的系统调用是如何发生的。使用此命令来查看这段程序使用的系统调用:

可以看到三次putchar被合并为了一次write系统调用,这种合并系统调用大幅降低内核态 / 用户态切换耗时

http://www.gsyq.cn/news/1456116.html

相关文章:

  • 基于MOSFET与RC电路的延时开关设计:从原理到实践
  • FLUX.1-dev精度评估:ClipScore与Hpsv2测试全流程
  • 如何让旧Mac焕发新生:3步解锁突破性系统兼容方案
  • Python自动化实战:从脚本工具到自动化框架的演进之路
  • 如何让2008-2017年的老款Mac焕发新生:OpenCore Legacy Patcher完全指南
  • 如何轻松解决Cursor试用限制?免费重置工具使用完全指南
  • 工业防爆监控选型科普|湖北区域 5 家优质供应商技术特点汇总
  • 【RT-DETR实战】122、算能(Sophgo)TPU平台部署探索:从模型转换到性能调优的血泪史
  • 从国内标杆到海外主力!苏州大向集成房屋中标乌克兰战后安置房项目,印证硬核制造实力 - 新闻快传
  • 家里瓷砖空鼓,翘边别乱修!2026 合肥瓷砖空鼓专业维修公司 TOP5 排名及专业性与口碑调研解析卫生间空鼓翘边,厨房空鼓翘边,客厅空鼓翘边,最新深度调研解析 - 防水资讯
  • AI写作辅助平台推荐
  • Baichuan-13B-Chat部署优化:5个技巧提升模型推理速度和效率
  • 【RT-DETR实战】123、FPGA部署DNN概述与HLS入门:从一次深夜调试说起
  • ROS 2 YOLO视觉系统:从2D感知到3D智能的完整机器人视觉解决方案
  • Step-Audio-Chat震撼发布:1300亿参数多模态语音大模型如何重塑人机交互体验?
  • 别再死记硬背B/M/E/S了!用Python手把手带你跑通HMM中文分词(附完整代码与语料)
  • 太强了!输入关键词,这几款AI论文写作工具自动生成毕业论文初稿!
  • 自动驾驶协同感知架构的车道变换预测技术
  • 信创迁移:Oracle切换海量数据库,慢sql扫描
  • 【RT-DETR实战】124、使用Vitis AI在FPGA上部署RT-DETR:从模型量化到板卡推理的实战踩坑记录
  • BALF框架:无需微调的模型压缩技术解析
  • 【新手向】 OpenClaw 部署分享,一键式安装包简化繁琐流程(含安装包)
  • 别只看落款印章!字画鉴藏真正核心不在这 - 深鉴新闻
  • kkfile安全预览minio的文件
  • 图论入门:从基础到遍历算法
  • 免费高效的跨语言语义工具:cross-en-de-fr-roberta-sentence-transformer安装与配置指南
  • 小型运油船价格多少 - 舒雯文化
  • Python中模块导入方式
  • Logback 1.5.34 发布:修复反序列化漏洞,增强异常处理能力
  • 2026婚纱摄影行业白皮书:丽江影楼合规标杆与市场真相 - GrowthUME