Linux文件IO缓存

一、缓冲区大小对 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.mzph.cn/pingmian/52685.shtml

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

相关文章

ArcGIS Pro技术应用

GIS是利用电子计算机及其外部设备&#xff0c;采集、存储、分析和描述整个或部分地球表面与空间信息系统。简单地讲&#xff0c;它是在一定的地域内&#xff0c;将地理空间信息和 一些与该地域地理信息相关的属性信息结合起来&#xff0c;达到对地理和属性信息的综合管理。GIS的…

Hreflang 和 SEO:新手完整指南

每天&#xff0c;数以百万计的法国用户访问像 Amazon.com 这样的全球网站。虽然 Amazon.com 的官方页面是英文的&#xff0c;但用户仍然可以看到法语的文本和产品描述。这是因为亚马逊的全球网站有针对法国的本地化版本&#xff0c;确保所有法国用户都可以自动看到法语的网站内…

五种多目标优化算法(NSGA3、MOPSO、MOGWO、NGSA2、SPEA2)性能对比,包含47个多目标测试函数,6种评价指标,MATLAB代码

一、五种多目标算法及六种评价指标简介 多目标灰狼优化算法&#xff08;MOGWO&#xff09;&#xff1a; MOGWO是由Mirjalili等人在2016年提出的&#xff0c;基于灰狼优化算法&#xff08;GWO&#xff09;的多目标版本。它引入了存档机制和改进的头狼选择方式&#xff0c;以处理…

uniapp(微信小程序如何使用单选框、复选框)

一、先看效果 二、数据结构 说明&#xff1a;selected用来记录每次用户选择的值&#xff0c;当是单选的时候属性中的selected属性需要设置成字符串&#xff0c;当是复选框的时候&#xff0c;此时选择的是数组&#xff0c;selected属性应设置为数组。type用来区分当前是单选还是…

【C++ Qt day3】

2、设计一个Per类&#xff0c;类中包含私有成员:姓名、年龄、指针成员身高、体重&#xff0c;再设计一个Stu类&#xff0c;类中包含私有成员:成绩、Per类对象p1&#xff0c;设计这两个类的构造函数、析构函数和拷贝构造函数。

PTA L1-027 出租

L1-027 出租&#xff08;20分&#xff09; 下面是新浪微博上曾经很火的一张图&#xff1a; 一时间网上一片求救声&#xff0c;急问这个怎么破。其实这段代码很简单&#xff0c;index数组就是arr数组的下标&#xff0c;index[0]2 对应 arr[2]1&#xff0c;index[1]0 对应 arr[0…

Java的IO模型详解-BIO,NIO,AIO

一、BIO相关知识 Java 的 BIO (Blocking I/O) 模型是基于传统的同步阻塞 I/O 操作。在这种模型中&#xff0c;每个客户端连接都需要一个独立的线程来处理请求。当线程正在执行 I/O 操作时&#xff08;如读取或写入&#xff09;&#xff0c;它会被阻塞&#xff0c;直到操作完成…

【读点论文】Scene Text Detection and Recognition: The Deep Learning Era

Scene Text Detection and Recognition: The Deep Learning Era Abstract 随着深度学习的兴起和发展&#xff0c;计算机视觉发生了巨大的变革和重塑。场景文本检测与识别作为计算机视觉领域的一个重要研究领域&#xff0c;不可避免地受到了这波革命的影响&#xff0c;从而进入…

Golang | Leetcode Golang题解之第376摆动序列

题目&#xff1a; 题解&#xff1a; int wiggleMaxLength(int* nums, int numsSize) {if (numsSize < 2) {return numsSize;}int prevdiff nums[1] - nums[0];int ret prevdiff ! 0 ? 2 : 1;for (int i 2; i < numsSize; i) {int diff nums[i] - nums[i - 1];if ((…

TD学习笔记————中级教程总结(NEW)

目录 Instance功能讲解 问题&#xff1a; 报错All ops must generate the same number of instances (have the same length Replicator功能讲解 问题&#xff1a; 视频分辨率过大 Cannot find function named:onValueChange Instance功能讲解 数据通道的长度要一致 N…

安泰功率放大器应用领域:MEMS传感器的应用有哪些

功率放大器的应用领域很广泛&#xff0c;从超声测试、材料测试、水声测试再到压电驱动、电磁驱动生物医疗&#xff0c;它都能为整个系统提供强劲的激励&#xff0c;同样功率放大器在MEMS传感器系统的激励中也有着良好应用&#xff0c;今天Aigtek安泰电子就带大家走进MEMS传感器…

Hadoop: Mapreduce了解

目录 1.MapReduce概述 2.MapReduce的基本工作原理 2.1.Map阶段 2.1.1.Map源码解析 2.1.2.map端代码总结 2.2.Shuffle and Sort阶段 2.3.Reduce阶段 2.3.1.Reduce源码解析 2.3.2.Reduce端源码总结 3.数据流与任务执行 3.1.数据输入与输出格式 3.1.1.TextInputFormat…

comfyui工作流,动漫转真人,效果炸裂!

在数字媒体制作领域&#xff0c;将动漫风格的图像转换为接近真人风格的视觉效果一直是一个具有挑战性的任务。最近&#xff0c;ComfyUI 推出了一套高级工具和节点系统&#xff0c;极大地简化了这一过程。本文将详细介绍这一工作流的各个组成部分以及其实用性。 工作流核心节点简…

使用腾讯云宝塔面板部署后端项目,包括MySQL,Redis,JDK,Maven

一、购买腾讯云服务器并配置 购买腾讯云的一个服务器服务后进入到如下页面&#xff0c;点击左侧栏服务器&#xff0c;然后点击“重装系统” 选择“使用应用面板”->“宝塔Linux面板”->填写自定义账号和密码->点击确认 二、配置宝塔服务器端口参数并启动 点击确认之…

2024年6月GSEP(C++)一级认证真题讲解

注意&#xff01;做题时长为2小时&#xff0c;孩子做完题目后对照讲解视频和讲解分析&#xff0c;针对薄弱点&#xff0c;进行有效的专项提高。 &#x1f451;讲解视频 &#xff08;暂无&#xff09; &#x1f451;讲解分析 1 单选题&#xff08;每题 2 分&#xff0c;共 3…

sqli-labs靶场通关攻略 46-50

主页有sqli-labs靶场通关攻略 1-45 第四六关 less-46 步骤一&#xff1a;利用报错注入查询库 ?sort1 and updatexml(1,concat(0x7e,database(),0x7e),1) 步骤二&#xff1a;查询表名 ?sort1 and updatexml(1,concat(0x7e,(select group_concat(table_name)from informatio…

WebSocket通信学习笔记

1 简介 WebSocket是一种全双工通信协议&#xff0c;它允许客户端和服务器之间建立持久化的双向连接&#xff0c;从而在不频繁创建HTTP请求的情况下进行实时数据传输。与传统的HTTP协议相比&#xff0c;WebSocket更适合需要实时数据更新的应用场景&#xff0c;如聊天应用、实时…

IDEA没有SQL语句提示

解决已经在IDEA连接数据库&#xff0c;但是写SQL语句不会提示列名、属性之类的 Mapper 映射没有 SQL 提示 设置中搜索&#xff0c;把方言改成 MySQL SQL Dialects

群晖(Docker Compose)配置 frp 服务

为了方便远程电脑&#xff0c;访问自己电脑上的ComfyUI等服务&#xff0c;配置了 frp 服务。 配置 frp 服务后&#xff0c;发现群晖中的一些服务也可以 stcp 安全的暴露出来。 直接在群晖通过 Docker Compose 方式部署 frps 和 frpc&#xff0c;访问者通过 frpc 安全访问暴露…

【机器学习】支持向量机(SVM)的对偶性、核方法以及核技巧

引言 在SVM中&#xff0c;通过引入拉格朗日乘子&#xff0c;可以将原始问题转化为对偶问题&#xff0c;这种转换具有几个重要的优点&#xff0c;包括简化计算和提供更直观的优化问题的解释 文章目录 引言一、支持向量机&#xff08;SVM&#xff09;的对偶性1.1 原始问题&#x…