Linux文件IO缓存

news2024/9/21 16:16:52

一、缓冲区大小对 I/O 系统调用性能的影响

  1. 总之,如果与文件发生大量的数据传输,通过采用大块空间缓冲数据,以及执行更少的 系统调用,可以极大地提高 I / O 性能

二、stdio 库的缓冲

  1. 当操作磁盘文件时,缓冲大块数据以减少系统调用,C 语言函数库的 I/O 函数(比如, fprintf()、fscanf()、fgets()、fputs()、fputc()、fgetc())正是这么做的。因此,使用 stdio 库可以 使编程者免于自行处理对数据的缓冲。

三、设置一个stdio流的缓冲模式

  1. 调用 setvbuf()函数,可以控制 stdio 库使用缓冲的形式

添加图片注释,不超过 140 字(可选)

2. 参数 stream 标识将要修改哪个文件流的缓冲。打开流后,必须在调用任何其他 stdio 函数 之前先调用 setvbuf()。setvbuf()调用将影响后续在指定流上进行的所有 stdio 操作。

3. 参数 buf 和 size 则针对参数 stream 要使用的缓冲区,指定这些参数有如下两种方式。

  • 如果参数 buf 不为 NULL,那么其指向 size 大小的内存块以作为 stream 的缓冲区。因 为 stdio 库将要使用 buf 指向的缓冲区,所以应该以动态或静态在堆中为该缓冲区分配 一块空间(使用 malloc()或类似函数),而不应是分配在栈上的函数本地变量。否则,函 数返回时将销毁其栈帧,从而导致混乱。

  • 若 buf 为 NULL,那么 stdio 库会为 stream 自动分配一个缓冲区(除非选择非缓冲的 I/O,如下所述)

4. 参数 mode 指定了缓冲类型,并具有下列值之一

5. setbuf()函数构建于setvbuf()之上,执行了类似任务

#include <stdio.h> 
int setvbuf(FILE *stream, char *buf, int mode, size_t size);
  • setbuf(fp,buf)调用除了不返回函数结果外,就相当于:

setvbuf(fp, buf, ()buf!=NULL)? _IOFBF:_IONBUF, BUF_SIZE);
  • BUFSIZ 定义于<stdio.h>头文件中。

6. setbuffer()函数类似于 setbuf()函数,但允许调用者指定 buf 缓冲区大小。

#define _BSD_SOURCE
#include <stdio.h>
void setbuffer(FILE* stream,char* buf,size_T size);

三、同步 I/O 数据完整性和同步 I/O 文件完整性

  1. SUSv3 定义的第一种同步 I/O 完成类型是 synchronized I/O data integrity completion,旨在 确保针对文件的一次更新传递了足够的信息(到磁盘),以便于之后对数据的获取。

  2. Synchronized I/O file integrity completion 是 SUSv3 定义的另一种同步 I/O 完成,也是上述 synchronized I/O data integrity completion 的超集。该 I/O 完成模式的区别在于在对文件的一次 更新过程中,要将所有发生更新的文件元数据都传递到磁盘上,即使有些在后续对文件数据 的读操作中并不需要。

四、刷新缓冲区

  1. 无论当前采用何种缓冲区模式,在任何时候,都可以使用 fflush()库函数强制将 stdio 输出流中的数据(即通过 write())刷新到内核缓冲区中

#include <stdio.h>
int fflush(FILE *stream);
  1. 若参数 stream 为 NULL,则 fflush()将刷新所有的 stdio 缓冲区。

  2. 也能将 fflush()函数应用于输入流,这将丢弃业已缓冲的输入数据。(当程序下一次尝试从 流中读取数据时,将重新装满缓冲区。)

  3. 当关闭相应流时,将自动刷新其 stdio 缓冲区。

  4. 若打开一个流同时用于输入和输出,则 C99 标准中提出了两项要求。首先,一个输出操作不能紧跟一个输入操作,必须在二者之间调用 fflush()函数或是一个文件定位函数 (fseek()、fsetpos()或者 rewind())。其次,一个输入操作不能紧跟一个输出操作,必须在二者之间调用一个文件定位函数,除非输入操作遭遇文件结尾。

四、控制文件 I/O 的内核缓冲

  1. 用于控制文件 I/O 内核缓冲的系统调用

  2. fsync()系统调用将使缓冲数据和与打开文件描述符 fd 相关的所有元数据都刷新到磁盘 上。

#include <unistd.h>
int fsync(int fd);

2. 仅在对磁盘设备(或者至少是其高速缓存)的传递完成后,fsync()调用才会返回。

3. fdatasync()系统调用的运作类似于 fsync(),只是强制文件处于 synchronized I/O data integrity completion 的状态。

 
 

#include <unistd.h>int fdatasync(int fd);

4. fdatasync()可能会减少对磁盘操作的次数,由 fsync()调用请求的两次变为一次。例如,若 修改了文件数据,而文件大小不变,那么调用 fdatasync()只强制进行了数据更新。

5. 在 Linux 实现中,sync()调用仅在所有数据已传递到磁盘上(或者至少高速缓存)时返回。

#include <unistd.h>void sync(void);

五、使所有写入同步:O_SYNC

  1. 调用 open()函数时如指定 O_SYNC 标志,则会使所有后续输出同步(synchronous)。

 
 

fd = open(pathname,O_WRONLY|O_SYNC)

2. 调用 open()后,每个 write()调用会自动将文件数据和元数据刷新到磁盘上(即,按照 Synchronized I/O file integrity completion 的要求执行写操作)。

3. 总之,如果需要强制刷新内核缓冲区,那么在设计应用程序时就应考虑是否可以使用大 尺寸的 write()缓冲区,或者在调用 fsync()或 fdatasync()时谨慎行事,而不是在打开文件时就使用 O_SYNC 标志。

六、O_DSYNC 标志

  1. O_DSYNC 标志要求写操作按照 synchronized I/O data integrity completion 来执行(类似于 fdatasync())。与之相映成趣的是 O_SYNC 标志,遵从 synchronized I/O file integrity completion (类似于 fsync()函数)。

七、I/O缓冲小结

  1. 首先是通过 stdio 库将用户数据传递到 stdio 缓冲区,该缓冲区 位于用户态内存区。当缓冲区填满时,stdio 库会调用 write()系统调用,将数据传递到内核高 速缓冲区(位于内核态内存区)。最终,内核发起磁盘操作,将数据传递到磁盘。

添加图片注释,不超过 140 字(可选)

八、就I/O模式向内核提出建议

  1. posix_fadvise()系统调用允许进程就自身访问文件数据时可能采取的模式通知内核

添加图片注释,不超过 140 字(可选)

advice

含义

POSIX_FADV_NORMAL

进程对访问模式并无特别建议。如果没有建议,这就是默认行为。在 Linux 中,该操作将文件预读窗口大小置为默认值(128KB)。

POSIX_FADV_SEQUENTIAL

进程预计会从低偏移量到高偏移量顺序读取数据。在 Linux 中,该操作将文件预读窗口大小置为默认值的两倍。

POSIX_FADV_RANDOM

进程预计以随机顺序访问数据。在 Linux 中,该选项会禁用文件预读。

POSIX_FADV_WILLNEED

进程预计会在不久的将来访问指定的文件区域。内核将由 offset 和 len 指定区域的文件数 据预先填充到缓冲区高速缓存中。后续对该文件的 read()调用将不会阻塞磁盘 I/O,只需从缓 冲区高速缓存中抓取数据即可。

POSIX_FADV_DONTNEED

进程预计在不久的将来将不会访问指定的文件区域。这一操作给内核的建议是释放相关的高速缓存页面(如果存在的话)。

POSIX_FADV_NOREUSE

进程预计会一次性地访问指定文件区域,不再复用。这等于提示内核对指定区域访问一 次后即可释放页面。在 Linux 中,该操作目前不起作用

九、绕过缓冲区高速缓存:直接 I/O

  1. Linux 允许应用程序在执行磁盘 I/O 时绕过缓冲区高速缓存,从用户空间直 接将数据传递到文件或磁盘设备。有时也称此为直接 I/O(direct I/O)或者裸 I/O(raw I/O)。

  2. 直接 I/O 只适用于有特定 I/O 需求的应用。例如数据库系统,其高速缓存和 I/O 优化机制均自成一体,无需内核消耗 CPU 时间和内存去完成相同任务。

可针对一个单独文件或块设备(比如,一块磁盘)执行直接 I/O。要做到这点,需要在调 用 open()打开文件或设备时指定 O_DIRECT 标志。

  1. 若一进程以 O_DIRECT 标志打开某文件,而另一进程以普通方式(即使用了高速缓存 缓冲区)打开同一文件,则由直接 I/O 所读写的数据与缓冲区高速缓存中内容之间不存在 一致性。应尽量避免这一场景。

十、直接 I/O 的对齐限制

  1. 因为直接 I/O(针对磁盘设备和文件)涉及对磁盘的直接访问,所以在执行 I/O 时,必须 遵守一些限制。

  2. 用于传递数据的缓冲区,其内存边界必须对齐为块大小的整数倍。

  3. 数据传输的开始点,亦即文件和设备的偏移量,必须是块大小的整数倍。

  4. 待传递数据的长度必须是块大小的整数倍。

十一、混合使用库函数和系统调用进行文件 I/O

  1. 在同一文件上执行 I/O 操作时,还可以将系统调用和标准 C 语言库函数混合使用。fileno() 和 fdopen()函数有助于完成这一工作。

#include <stdio.h> 
fileno(FILE *stream); 
FILE *fdopen(int fd, const char *mode);
  1. fdopen()函数对非常规文件描述符特别有用。正如后续章节将提及的,创建套接字和管道 的系统调用总是返回文件描述符。为了在这些文件类型上使用 stdio 库函数,必须使用 fdopen() 函数来创建相应文件流。

  2. 当使用 stdio 库函数,并结合系统 I/O 调用来实现对磁盘文件的 I/O 操作时,必须将缓冲问题牢记于心。I/O 系统调用会直接将数据传递到内核缓冲区高速缓存,而 stdio 库函数会等 到用户空间的流缓冲区填满,再调用 write()将其传递到内核缓冲区高速缓存。

#include <stdio.h> 
#include <unistd.h> 
int main() 
{
    printf("To man the world is twofold, "); //fflush(stdout);
    setbuf(stdout,NULL);
    write(STDOUT_FILENO,"in accordance with his twofold attitude.\n",41);
}
 

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

合宙LuatOS产品规格书——Air700EAQ

Luat Air700EAQ是合宙的LTE Cat.1bis通信模块&#xff0c;采用移芯EC716E平台&#xff0c;支持LTE 3GPP Rel.13技术。 该模块专为满足小型化、低成本需求而设计&#xff0c;具备超小封装和极致成本优势。 Air700EAQ支持移动双模&#xff0c;内置丰富的网络协议&#xff0c;集…

Qt第二十章 数据库操作

文章目录 Qt操作数据库QSqlDataBaseQSqlQuery执行SQL语句 QSqlRecordQSqlField数据库模型QSqlQueryModelQSqlTableModelQSqlRelationalTableModel 编译MySql驱动msvc版本MySql客户端程序部署 Qt操作数据库 需要在cmakelist加上Sql模块 QSqlDataBase 可以通过静态成员查看支持的…

北京青蓝智慧科技:2024(第九届)世界物联网大会将于11月在京举行

2024年11月&#xff0c;北京将迎来第九届世界物联网大会的盛大启幕。 这一年度盛会由世界物联网大会、中国移动通信联合会、外交理事会携手举办&#xff0c;得到了世界绿色设计组织、世界物联网基金会等机构的大力支持。 大会的宗旨在于推动全球智能联网数字经济的创新进展&a…

Golang | Leetcode Golang题解之第373题查找和最小的K对数字

题目&#xff1a; 题解&#xff1a; func kSmallestPairs(nums1, nums2 []int, k int) (ans [][]int) {m, n : len(nums1), len(nums2)// 二分查找第 k 小的数对和left, right : nums1[0]nums2[0], nums1[m-1]nums2[n-1]1pairSum : left sort.Search(right-left, func(sum in…

Notion 使用详解——基础教程

《Notion 使用详解——基础教程》 一、Notion简介 Notion是一款集笔记、任务、数据库、wiki、知识库等功能于一体的生产力工具&#xff0c;其强大的模块化设计和高度自定义能力&#xff0c;使其成为个人和团队提高工作效率的理想选择。 二、基础操作 1. 创建页面&#xff1a;…

几个很棒的AI问题和精彩回答

这里有几个很棒的与AI相关的问题和精彩的回答&#xff0c;分享给大家 2024&#xff0c;怎么以10倍的速度设计AI产品&#xff1f; 回答嘉宾&#xff1a;Tidyread作者 根据产品定位&#xff0c;对整体风格进行定调 Tidyread 希望人们能从中建立资讯阅读的秩序感&#xff0c;所以…

阿里云对象存储OSS的前端直传-demo

原由 在项目里有时候会碰到比如上传文件相关的&#xff0c;一般都是后端提供个接口&#xff0c;然后我们上传的时候后端再传到阿里OSS或者其他服务商的对象存储&#xff0c;然后把最终的url拿到存起来或者返回给前端&#xff0c;这种方式其实在上传图片的频率不高的业务场景中…

电商数据接口助力电商数据分析||电商运营每日必看5个底层数据

数据分析充电站——深入探索中小企业数字化转型&#xff0c;专注提供各行业数据分析干货、分析技巧、工具推荐以及各类超实用分析模板&#xff0c;为钻研于数据分析的朋友们加油充电。 电商运营店铺涉及大量数据&#xff0c;包括用户行为、交易记录、库存信息等&#xff0c;如何…

Python测试之测试覆盖率统计

本篇承接上一篇 Python测试框架之—— pytest介绍与示例&#xff0c;在此基础上介绍如何基于pytest进行测试的覆盖率统计。 要在使用 pytest 进行测试时检测代码覆盖率&#xff0c;可以使用 pytest-cov 插件。这个插件是基于 coverage.py&#xff0c;它能帮助你了解哪些代码部…

【PySide6-QML】2. 添加菜单栏

文章目录 前言实现添加菜单栏添加菜单添加子菜单点击动作添加快捷键 前章回顾&#xff1a;【PySide6-QML】1. 创建新项目 前言 本文使用 MenuBar 添加工具菜单栏&#xff0c;Action 添加子菜单&#xff0c;并添加快捷键和动作回调。 实现 添加菜单栏 import QtQuick.Contr…

centos mongodb安装+开机启动

1.mongodb安装 Centos系统中mongodb的安装详解_centos安装mongodb-CSDN博客 步骤1-下载 下载地址&#xff1a;Download MongoDB Community Server | MongoDB 步骤2-安装-修改配置 Centos系统中mongodb的安装详解_centos安装mongodb-CSDN博客 下载包到 /usr/local/ 解压 tar…

新一代RK3576芯片,3588平替吗?

瑞芯微RK3576是一款高性能、低功耗的SoC&#xff08;系统级芯片&#xff09;处理器&#xff0c;适用于基于ARM的PC、边缘计算设备、个人移动互联网设备等多种应用场景。它采用Arm架构的八核心CPU&#xff0c;集成了GPU、MCU、NPU、VPU等多种计算核心&#xff0c;并具有丰富的外…

基于深度学习的交通标志检测识别系统(含UI界面、yolov5、Python代码、数据集)

项目介绍 项目中所用到的算法模型和数据集等信息如下&#xff1a; 算法模型&#xff1a;     yolov5、yolov5 SE注意力机制&#xff0c;两个模型都已训练好&#xff0c;可直接使用。 数据集&#xff1a;     网上下载的数据集&#xff0c;格式都已转好&#xff0c;可…

K8S对接Ceph分部署存储

文章目录 一、Ceph理论知识1、Ceph简介2、Ceph分布式存储的优点3、Ceph核心组件 二、部署Ceph高可用集群1、服务器环境信息2、部署前环境准备工作3、部署Ceph监控服务Monitor4、激活Ceph存储服务OSD 三、K8S对接Ceph存储1、K8S对接Ceph RBD实现数据持久化2、基于Ceph RBD生成PV…

【精选】基于数据可视化的智慧社区内网平台(程序员阿龙出品精品)

博主介绍&#xff1a; ✌我是阿龙&#xff0c;一名专注于Java技术领域的程序员&#xff0c;全网拥有10W粉丝。作为CSDN特邀作者、博客专家、新星计划导师&#xff0c;我在计算机毕业设计开发方面积累了丰富的经验。同时&#xff0c;我也是掘金、华为云、阿里云、InfoQ等平台…

游戏出海,燃动全球,“安全”如何通关?

泼天的富贵落在了游戏圈&#xff0c;用事实打脸了男人消费不如狗的谬论。 这几天&#xff0c;无论是游戏圈内人还是圈外人&#xff0c;无人不知晓《黑神话&#xff1a;悟空》。这部头顶「3A国产游戏之光」的作品自6月8日预售以来&#xff0c;全平台销量超过800万份&#xff0c;…

基于R语言的统计分析基础:数据结构

R语言是一种用于统计分析和图形表示的编程语言和软件环境&#xff0c;它提供了多种数据结构以存储和操作数据。这些数据结构包括向量、矩阵、数组、数据框、列表、因子、Tibble、环境、公式、调用以及表达式。 向量&#xff08;Vector&#xff09; 向量是R中最基本的数据结构…

InstantID: Zero-shot Identity-Preserving Generation in Seconds

https://arxiv.org/pdf/2401.07519#page9.73https://github.com/instantX-research/InstantID?tabreadme-ov-filehttps://github.com/instantX-research/InstantID/pull/89/files 问题引入 目标是生成和reference图片相符合的图片&#xff0c;特别是人脸&#xff1b;现在基于…

C++必修:unordered_set/unordered_map

✨✨ 欢迎大家来到贝蒂大讲堂✨✨ &#x1f388;&#x1f388;养成好习惯&#xff0c;先赞后看哦~&#x1f388;&#x1f388; 所属专栏&#xff1a;C学习 贝蒂的主页&#xff1a;Betty’s blog 1. unordered_set的介绍 unordered_set是一种关联式容器&#xff0c;它具有以下几…

使用MVC设计模式根据软件系统设计建设高校数字化教育教学资源共享平台

目录 案例 【题目】 【问题 1】(9 分) 【问题 2】(6 分) 【问题 3】(10 分) 答案 【问题 1】答案 【问题 2】答案 【问题 3】解析 相关推荐 案例 阅读以下关于软件系统设计的叙述&#xff0c;在答题纸上回答问题 1 至问题 3。 【题目】 某软件企业受该省教育部门委托…