linux系统编程——文件IO——分散聚集IO

1. 为什么需要向量IO

性能:
比较于线性IO,向量IO除了可以减少系统调用次数,还可以经内部优化提供性能改善
原子性:
进程可以单次向量IO,不会有与另一个进程操作交叉在一起的风险。

2. 使用说明

       ssize_t readv(int fd, const struct iovec *iov, int iovcnt);

       ssize_t writev(int fd, const struct iovec *iov, int iovcnt);

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

readv 和 writev 会按照顺序,依次操作 向量数组 iov 的 元素。

返回 读/写 的 字节总数,也就是 iovcnt 个 iov_len 的总和。

返回值为 ssize_t 类型,所以 能返回的最大值为 SSIZE_MAX,若总和大于这个数,则调用失败,返回-1

3. 示例

#include <bits/types/struct_iovec.h>
#include <stdio.h>
#include <sys/uio.h>
#include <string.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <signal.h>
#include <unistd.h>
#include <sys/types.h>
#include <stdlib.h>


int main()
{
        int fd, nr, i;
        struct iovec iov[3];
        char *buf[3] = {
                "hello aaaa\n",
                "hello bbbb\n",
                "hello cccc\n"
        };


        fd = open("./tmp", O_WRONLY | O_CREAT | O_TRUNC);

        for (i = 0; i < 3; i++) {
                iov[i].iov_base = buf[i];
                iov[i].iov_len = strlen(buf[i]);
        }

        nr = writev(fd, iov, sizeof(iov)/sizeof(*iov));
        if (nr == -1) {
                perror("writev");
                return 1;
        }

        printf("write %d bytes\n", nr);

        close(fd);

        return 0;
}
#include <bits/types/struct_iovec.h>
#include <stdio.h>
#include <sys/uio.h>
#include <string.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <signal.h>
#include <unistd.h>
#include <sys/types.h>
#include <stdlib.h>


int main()
{
        int fd, nr, i;
        struct iovec iov[3];
        char buf[3][20];

        fd = open("./tmp", O_RDONLY);


        memset(buf, 0x0, sizeof(buf));
        for (i = 0; i < 3; i++) {
                iov[i].iov_base = buf[i];
                iov[i].iov_len = 11;// 读的文本为 "hello xxxx\n" 一共11bytes
        }

        nr = readv(fd, iov, sizeof(iov)/sizeof(*iov));
        if (nr == -1) {
                perror("readv");
                return 1;
        }

        for (i = 0; i < 3 ; i++) {
                printf("%d : %s\n", i, (char *)iov[i].iov_base);
        }

        close(fd);

        return 0;
}

4. uio 和 普通IO的关系

内核所有IO都使用向量方式,所以 read write 被实现为 向量只有一段的 向量IO

posted on   开心种树  阅读(105)  评论(0编辑  收藏  举报

编辑推荐:
· .NET Core 中如何实现缓存的预热?
· 从 HTTP 原因短语缺失研究 HTTP/2 和 HTTP/3 的设计差异
· AI与.NET技术实操系列:向量存储与相似性搜索在 .NET 中的实现
· 基于Microsoft.Extensions.AI核心库实现RAG应用
· Linux系列:如何用heaptrack跟踪.NET程序的非托管内存泄露
阅读排行:
· TypeScript + Deepseek 打造卜卦网站:技术与玄学的结合
· Manus的开源复刻OpenManus初探
· 三行代码完成国际化适配,妙~啊~
· .NET Core 中如何实现缓存的预热?
· 阿里巴巴 QwQ-32B真的超越了 DeepSeek R-1吗?
< 2025年3月 >
23 24 25 26 27 28 1
2 3 4 5 6 7 8
9 10 11 12 13 14 15
16 17 18 19 20 21 22
23 24 25 26 27 28 29
30 31 1 2 3 4 5

统计

点击右上角即可分享
微信分享提示