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;
}

Authorthebesttv
Created2022-10-22 16:07
Modified2022-10-22 17:06
Generated2024-06-11 02:39
VersionEmacs 29.3 (Org mode 9.6.15)
Rawvectored-io.org