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