Vectored IO
在做网络编程的 异步TCP 作业的时候, 想用 liburing,
发现要先学一下 readv() 和 writev():
1. What is Vectored IO
Vectored IO is doing IO with a vector of buffers, instead of using
just a single buffer as in read() and write(). It is also called
scatter/gather IO, as it scatters data into, or gathers data from, a
set of buffers.
2. Vectored IO in Linux
readv() (scatter input) and writev() (gather output) are Linux
implementations of vectored IO. They share the exact same signature:
#include <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);
Here iov is an array of buffers, and iovcnt is the length of the
array (i.e. it counts how many buffers there are in the array). A
description of the iov array from man 3 iovec:
each element of the array represents a memory region, and the whole array represents a vector of memory regions.
Each buffer in the iov array is a struct iovec:
#include <sys/uio.h> struct iovec { void *iov_base; /* Starting address */ size_t iov_len; /* Size of the memory pointed to by iov_base. */ };
3. Comparison with read() & write()
Traditional read() and write() functions have similar signatures
except for the single buffer buf, which is non-const with read()
(as data is written to buf) and const with write() (as data is
only read from buf).
#include <unistd.h> ssize_t read(int fd, void *buf, size_t count); ssize_t write(int fd, const void *buf, size_t count);
4. Examples
4.1. write()
Printing a message to stdout with write():
#include <stdio.h> // perror() #include <stdlib.h> // exit(), EXIT_SUCCESS, EXIT_FAILURE #include <unistd.h> // write(), STDOUT_FILENO int main() { const char buf[] = "Hello world from thebesttv!\n"; if (write(STDOUT_FILENO, buf, sizeof(buf)) == -1) { perror("write()"); exit(EXIT_FAILURE); } return EXIT_SUCCESS; }
4.2. writev()
Splitting the message into 3 separate buffers and printing them to
stdout with writev():
#include <stdio.h> // perror() #include <string.h> // strlen() #include <stdlib.h> // exit(), EXIT_SUCCESS, EXIT_FAILURE #include <unistd.h> // STDOUT_FILENO #include <sys/uio.h> // vectored IO: iovec, writev() #define LENGTH 3 int main() { const char *bufs[LENGTH] = {"Hello ", "world ", "from thebesttv!\n"}; struct iovec vecs[LENGTH]; for (int i = 0; i < LENGTH; i++) { vecs[i].iov_base = (void *)bufs[i]; vecs[i].iov_len = strlen(bufs[i]); }; if (writev(STDOUT_FILENO, vecs, LENGTH) == -1) { perror("writev()"); exit(EXIT_FAILURE); } return EXIT_SUCCESS; }