linux中I/O流中的全缓冲、行缓冲和无缓冲,简明实例演示

2023-11-17

说到缓冲,缓存之类的术语,通常都会和执行效率联系到一起,在标准I/O库中提供缓冲的主要目的就是减少系统函数read和write的调用,从而能够减少系统CPU时间。标准I/O库的缓冲主要分为3种:全缓冲、行缓冲和不缓冲。笔者就3种缓冲写了一些示例,帮助理解。

1、全缓冲

全缓冲就是当输入或输出时,当缓冲区被填满了之后,才会进行实际的I/O操作。下面是一个将”hello world!“写入log.txt文件的程序,演示了这一个过程。log.txt是空文件,长度为0。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
# include <stdio.h>
# include <stdlib.h>
# include <errno.h>
 
int main(void)
{
     FILE *stream;
     if ((stream = fopen ( "./log.txt" , "a" )) == NULL) {
         printf( "error: %d\n" , errno);
         exit (1);
     }
     
     char buf[BUFSIZ];
     setvbuf(stream, buf, _IOFBF,  BUFSIZ);
     fputs ( "hello world!" , stream);
 
     sleep(20);
 
     return 0;
}

上例代码通过setvbuf函数设定stream流是全缓冲,_IOFBF表示io full buffer的意思,编译执行这个程序,然后立马查看log.txt文件:

$ ls -l log.txt
-rw-r--r-- 1 root root 0 Nov 20 22:40 log.txt

会发现文件的长度是0,直到睡眠结束后,字符” hello world!“才会写入到log.txt文件。

如果fputs了很多次后,长度还是小于BUFSIZ,但是需要将这些内容都实际写入文件,可以使用fflush函数。fflush函数根据指定的文件流将缓冲区的内容进行实际的操作,并清空缓冲区;如果参数为NULL,则会对所有打开的文件流操作。例如上例,只要在fputs(“hello world!”, stream);代码后面加上下面一行代码就OK了。

1
fflush (stream);

编译执行代码,可以发现即使程序还在睡眠,但是内容已经写入log.txt了。

2、行缓冲

当在输入或输出中遇到换行符时,才进行实际I/O操作。linux下标准输出默认是行缓冲,下面的例子使用标准输出演示这一个过程。

1
2
3
4
5
6
7
8
9
10
11
12
# include <stdio.h>
 
int main(void)
{
     fputs ( "hello" , stdout);
     sleep(2);
     //这里一开始输出了换行符,所以前面的hello就被输出到屏幕上了。
     fputs ( "\nworld" , stdout);
     sleep(2);
 
     return 0;
}

编译执行上面的程序,应当看到过两秒才会输出一个”hello“,再过两秒才输出”word“,然后程序就结束了。在C语言中,可以通过setvbuf来设定缓冲模式,其中_IOLBF表示行缓冲,就是IO line buffer的意思。

3、无缓冲

标准I/O库不进行任何字符缓冲,任何读写都是即时可见的。linux下标准错误输出默认是不缓冲,修改上面的例子:

1
2
3
4
5
6
7
8
9
10
11
# include <stdio.h>
 
int main(void)
{
     fputs ( "hello" , stderr);
     sleep(2);
     fputs ( "world" , stderr);
     sleep(2);
 
     return 0;
}

编译执行上面的程序,结果就比较显而易见了。程序一执行的时候就会输出”hello“,过两秒输出”world“,再过两秒程序就结束了。在C语言中,可以通过setbuf来设定无缓冲模式,只要将第二个参数设置为NULL就可以了;也可以通过setvbuf来设定无缓冲模式,其中_IONBF表示行缓冲,就是IO not buffer的意思。




FROM: http://www.01happy.com/linux-io-buffer/

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

linux中I/O流中的全缓冲、行缓冲和无缓冲,简明实例演示 的相关文章

  • 基于C#的数据库文件管理助手

    我们经常会遇到这样的问题 在数据库中的文件存放的是web格式或者是绝对路径 以及使用的是百度上传或者其他上传组件 造成了很多异步上传的冗余文件 如果客户需要我们导出企业官网中的产品图片 我们该如何处理 很简单 当然是自己写个工具来读取 然后
  • obsidian memos插件iphone端无法读取memos

    首先看periodic或者daily插件有没有问题 其次看dateview插件是否达到要求的0 5 9以上 如果是手机端不行但电脑端可以的话一般来说插件配置是没问题的 除非手机app有哪里不兼容 都没有问题的话可能是 memos插件在手机上
  • CMake中cmake_minimum_required的使用

    CMake中的命令cmake minimum required用于设定需要的最低版本的CMake 其格式如下 cmake minimum required VERSION
  • 与窗口大小无关的图像滤波算法

    问题 一幅24位彩色图像 其上有一些红色区域 这些区域都是相连的 为了将图像中红色且相连的部分分离出来 使用如下算法 对单个像素进行判断 若满足R 10 gt G且R 10 gt B 那么就认为该像素呈红色 因为图像原因 可能在某个位置孤立
  • spingboot+layui+poi实现excel导入功能,并批量插入数据库

    1 maven的pom文件添加下面jar包
  • 堆(Heap-线程共享)-运行时数据区

    是被线程共享的一块内存区域 创建的对象和数组都保存在 Java 堆内存中 也是垃圾收集器进行 垃圾收集的最重要的内存区域 由于现代VM采用分代收集算法 因此Java堆从GC的角度还可以 细分为 新生代 Eden 区 From Survivo
  • 2023深圳杯C题

    专栏内已发布ABCD篇 论文 思路 代码 只需订阅一次 目录 无人机协同避障航迹规划 摘要 一 问题重述 1 1 背景
  • 10分钟搞懂遗传算法

    大自然有种神奇的力量 它能够将优良的基因保留下来 从而进化出更加强大 更加适合生存的基因 遗传算法便基于达尔文的进化论 模拟了自然选择 物竞天择 适者生存 通过N代的遗传 变异 交叉 复制 进化出问题的最优解 遗传算法看似神奇 但实现思路却
  • ERROR 1045 (28000): Access denied for user ‘ODBC‘@‘localhost‘ (using password: NO)

    ERROR 1045 28000 Access denied for user ODBC localhost using password NO 这个问题是由于密码错误导致的 一般是要重置密码 可以修改my ini配置文件 1 用记事本打开
  • C语言中数组名和&数组名的区别

    C语言中数组名和 数组名的区别 include
  • 迁移学习源码全注释 - 《Tensorflow 实战 Google 深度学习框架》源码注释

    学习迁移学习源码 做了完全版本注释 以做记录 coding utf 8 Created on Mon Dec 25 12 30 25 2017 需要提前下载训练好的 Inception V3模型 以及对应的数据文件 author Admin
  • Linux - CentOS 6 安装 JDK

    安装步骤如下 1 下载jdk1 7 0 55 jdk 7u55 linux i586 tar gz 2 卸载系统自带的开源JDK 查看是否安装JDK rpm qa grep java 显示如下信息 存在 执行下面代码删除 rpm e jav

随机推荐

  • 智能营销增益模型(Uplift Modeling)实践整理

    一 uplift 思想 因果推断 常用的点击率预测模型 称为响应模型 response model 即预测用户看到商品 Treatment 后点击 购买 的概率 但在营销的发放优惠券这种场景下 很自然会想到 用户是本来就有购买的意愿还是因为
  • Java代码写好后怎么运行?

    对于很多Java初学者来说 编写好自己的第一个程序能够运行起来是一件非常自豪的事情 那么你知道应该如何才能运行Java代码吗 今天小千就来给大家介绍一下 Java代码运行方法 1 首先需要确保你的电脑正确安装了Java环境并且环境变量都配置
  • 设计模式的六大原则

    目的 高内聚 低耦合 基于 对接口编程而不是对实现编程 优先使用对象组合而不是继承 1 开闭原则 Open Close Principle 开闭原则的意思是 对扩展开放 对修改关闭 在程序需要进行拓展的时候 不能去修改原有的代码 实现一个热
  • STM32 PWM捕获方式:两种思想

    一 利用系统自带PWM捕获 1 代码 初始化 c include capture h include stm32f10x h void Capture Init PA7 gt TIM3 CH2 GPIO InitTypeDef GPIO I
  • springboot性能优化

    SpringBoot性能调优有三种方案 SpringBoot 是一个快速开发框架 能够快速的整合第三方框架 简化XML配置 全部采用注解形式 内置Tomcat容器 帮助开发者能够实现快速开发 SpringBoot的Web组件 默认集成的是S
  • 软件测试:白盒测试

    一 定义 白盒测试又称结构测试 透明盒测试 逻辑驱动测试或基于代码的测试 白盒测试是一种测试用例设计方法 盒子指的是被测试的软件 白盒指的是盒子是可视的 白盒 法全面了解程序内部逻辑结构 对所有逻辑路径进行测试 白盒 法是穷举路径测试 在使
  • webpack5搭建vue环境

    webpack5搭建vue环境 0 前言 安装 webpack webpack cli 开始我是全局安装进行测试 后期项目中最好用局部安装 不同项目使用的版本不同 熟悉 npm基本命令确保npm可以使用 1 webpack概念 中文官网 h
  • SQL语句的MINUS,INTERSECT和UNION ALL

    SQL语句中的三个关键字 MINUS 减去 INTERSECT 交集 和UNION ALL 并集 关于集合的概念 中学都应该学过 就不多说了 这三个关键字主要是对数据库的查询结果进行操作 正如其中文含义一样 两个查询 MINUS是从第一个查
  • vue实现下载文件和图片功能

    vue实现图片或文件下载功能 今天一个需求就是实现图片下载功能 刚开始以为很简单没有什么逻辑可写 就以为调用后端接口就可以了 调用之后发现有问 题 看来还是没有想象的那么简单 1 要自己创建一个a标签 以下就是下载功能的实现 这里是调用接口
  • 2.4 HTTP请求方法

    在客户端向服务器端发送请求时 需要确定使用的请求方法 请求方法表明对URL指定资源的操作方式 服务器会根据不同的请求方法进行不同的响应 在HTTP 1 1中 共定义了8种请求方法 具体如下 GET 请求指定的内容并返回 POST 向指定资源
  • 分布式缓存的切片模式-hash一致性切片

    文章目录 一 为什么使用缓存 二 为什么使用分布式 三 使用什么模式 四 常规切片模式的弊端 五 更加犀利的切片模式 hash一致性切片 六 不完美的数据倾斜以及解决方案 6 1 数据倾斜 6 2 解决办法 一 为什么使用缓存 当前 我们通
  • 基于stm32的keil调试

    目录 基于stm32的keil调试 前言 实验目的 问题 debug 定位问题 解决 总结 基于stm32的keil调试 本文目标 基于stm32的keil调试 按照本文的描述 应该可以跑通实验并举一反三 先决条件 装有编译和集成的开发环境
  • 06_个人注释版本(01版本)GTK播放器__基于Linux系统下的mplayer播放器

    include
  • 计算机视觉结合深度学习项目-智能停车场空车位实时识别

    欢迎来到本博客 本次博客内容将继续讲解关于OpenCV的相关知识 作者简介 目前计算机研究生在读 主要研究方向是人工智能和群智能算法方向 目前熟悉python网页爬虫 机器学习 计算机视觉 OpenCV 群智能算法 然后正在学习深度学习的相
  • Android框架源码解析之(五)Retrofit

    源码地址 https github com square retrofit Retrofit源码结构 可以看出Retrofit是使用idea maven依赖编写的Java工程 并不是一个Android 工程 Retrofit的简单使用 1
  • 学习docker之路(三)

    目录 一 docker容器内操作 二 网络 一 docker容器内操作 1 将容器导出为归档 docker export 容器名称 o 归档包名称 root localhost docker export 05 o mynginx v2 t
  • leetcode_165. Compare Version Numbers 比较版本大小

    题目 Compare two version numbers version1 and version2 If version1 gt version2 return 1 if version1 lt version2 return 1 o
  • git简单使用与安装(小白01)(还看不懂我下个版本给图片)

    一 1 下载git 在官网上下载 下载成功后 闭着眼睛狂点下一步 然后就成功了 嘿嘿 二 1 随便创建一个新的文件夹 打开文件夹点这里 下图 然后输入cmd 然后在按回车 cmd中输入 git init 生成git文件 该文件是隐藏状态 2
  • redis06_ redis的订阅发布模式(redis做MQ中间件)、持久化(rdb,aof)、事务

    一 redis订阅发布模式 1 1 简介 redis 可以做消息中间件 MQ message queue 通常通过订阅发布模式来实现 消息订阅发布模式 还可以基本数据类型Lists实现 点到点模式 可以使用lpush lpop 实现消息先进
  • linux中I/O流中的全缓冲、行缓冲和无缓冲,简明实例演示

    说到缓冲 缓存之类的术语 通常都会和执行效率联系到一起 在标准I O库中提供缓冲的主要目的就是减少系统函数read和write的调用 从而能够减少系统CPU时间 标准I O库的缓冲主要分为3种 全缓冲 行缓冲和不缓冲 笔者就3种缓冲写了一些