首页 分享 linux文件IO与内存映射:分散/聚集IO技术(scatter

linux文件IO与内存映射:分散/聚集IO技术(scatter

来源:花匠小妙招 时间:2025-01-02 04:58
前言

根据上文我们学习到的用户空间的IO缓冲区,操作系统为了减少系统调用的次数,节省系统开销,提出了用户空间的IO缓冲区,即为用户空间的文件读写开辟一段可以利用setvbuf配置大小的内存空间来作为文件IO缓冲区。

描述

为了在以上IO缓冲区的基础上更进一步得减少系统调用的次数,提出了分散/聚合IO技术,总体上是使用了单个向量的IO操作代替了多个向量的IO操作。
读文多个件的时候将从page cache中读到的内容先读入到一个IO缓冲区数据结构中,再由一个缓冲区分别分散返回到多个文件缓冲区中;写文件的过程与读文件的过程刚好相反,即将多个文件缓冲区的内容聚合写到一个缓冲区中,写入page cache中,从而更高得提升系统调用效率。

在这里插入图片描述

实现

实现scatter-gather技术的系统调用原型如下:

头文件<sys/uio.h>

函数使用:
ssize_t readv(int fd, const struct iovec *iov, int iovcnt);
ssize_t writev(int fd, const struct iovec *iov, int iovcnt);

函数参数
fd :打开的文件描述符
iov: IO向量数据结构内容如下,每个结构体成员代表一个buffer:

struct iovec { void *iov_base; /* Starting address */ size_t iov_len; /* Number of bytes to transfer */ }; 1234

iovcnt:IO向量的个数

这两个系统调用的底层仍然是使用read/write系统调用,只是对IO 缓冲区做了聚合,支持多个IO缓冲区内容聚合到同一个IO向量中

代码如下:
writev.c

#include <stdio.h> #include <stdlib.h> #include <unistd.h> #include <string.h> #include <sys/uio.h> #include <fcntl.h> int main(int argc, char *argv[]) {ssize_t count = 0;int fd, i = 0;char *buf[]={"buffer1n","buffer2n","buffer3n"};fd = open(argv[1], O_WRONLY|O_CREAT, 0666);if (-1 == fd) {printf("open failed n");_exit(-1);}//将三个IO缓冲区的文件聚合为一个IO向量struct iovec iov[3];for (i ; i < 3; ++i) {iov[i].iov_base = buf[i];iov[i].iov_len = sizeof(buf[i]) + 1;printf("iovec[%d] size is %ld n",i,iov[i].iov_len);}//写入一个文件count = writev(fd, iov, 3);if (-1 == count) {printf("writev failedn");_exit(-1);}close(fd);return 0; }

12345678910111213141516171819202122232425262728293031323334353637383940

readv.c

#include <stdio.h> #include <string.h> #include <stdlib.h> #include <unistd.h> #include <sys/uio.h> #include <fcntl.h> int main(int argc, char *argv[]) {ssize_t count = 0;int fd, i = 0;char buf1[9],buf2[9],buf3[9];//生成一个文件,可以传入聚合IO缓冲区的文件fd = open(argv[1], O_RDONLY,0666);if (-1 == fd) {printf("open failed n");_exit(-1);}//对IO向量中的各个IO缓冲区进行地址和内容大小赋值struct iovec iov[3];iov[0].iov_base = buf1;iov[0].iov_len = sizeof(buf1);iov[1].iov_base = buf2;iov[1].iov_len = sizeof(buf2);iov[2].iov_base = buf3;iov[2].iov_len = sizeof(buf3);//从page cache读入的一个向量会分散到三个缓冲区中count = readv(fd,iov,3);if (-1 == count) {printf("writev failedn");_exit(-1);}for (i ; i < 3; ++i) {printf(" %s",(char *)(iov[i].iov_base));}prinft("buf1 %sn",buf1);prinft("buf2 %sn",buf2);prinft("buf3 %sn",buf3);close(fd);return 0; }

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849

编译输出如下:
gcc writev.c -o writev
gcc readv.c -o readv

zhang@ubuntu:~/Desktop/cpp_practice$ ./writev writevfile iovec[0] size is 9 iovec[1] size is 9 iovec[2] size is 9 zhang@ubuntu:~/Desktop/cpp_practice$ ./readv writevfile buffer1 buffer2 buffer3 buf1 buffer1 buf2 buffer2 buf3 buffer3 12345678910111213

相关知识

Linux网络编程实战
嵌入式linux与ARM开发板的入门建议
Java IO 序列化流实现注册(Register)与登录(Login)
搜索关键词广告(SEM) · 诸葛io使用文档
蓝樱牡丹花
“基于三菱PLC和组态王的兰花灌溉控制系统——农业农田智能化解决方案,详解梯形图程序、接线图原理图和IO分配”
【智能商务】诸葛io于晓松:数字化营销解决方案&案例
菜根花小宝贝
Windows常见性能计数器 Total Processor Time
hive项目

网址: linux文件IO与内存映射:分散/聚集IO技术(scatter https://www.huajiangbk.com/newsview1406868.html

所属分类:花卉
上一篇: 鞣花酸固体分散体对带鱼氧化和品质
下一篇: 可乐瓶底为何设计成五瓣花形状

推荐分享