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 2021-08-23 09:36  开心种树  阅读(90)  评论(0编辑  收藏  举报