Vectored Reads and Writes

If the data that a process reads from a file in a single read needs to placed in different areas of memory, this would typically involve more than one call to read(). However, the readv() system call can be used to perform a single read from the file but copy the data to the multiple memory locations, which can cut down on system call overhead and therefore increase performance in environments where there is a lot of I/O activity. When writing to files the writev() system call can be used.

Here are the definitions for both functions:

#include <sys/uio.h>

ssize_t readv(int fildes, const struct iovec iov, int iovcnt);
ssize_t writev(int fildes, const struct iovec iov, int iovcnt);

Note that although multiple I/Os can be combined, they must all be contiguous within the file.

struct uio {
    void    *iov_base;  /* Address in memory of buffer for r/w */
    size_t  iov_len;    /* Size of the above buffer in memory */
}

Figure 3.1 shows how the transfer of data occurs for a read operation. The shading on the areas of the file and the address space show where the data will be placed after the read has completed.

The following program corresponds to the example shown in Figure 3.1:

1 #include <sys/uio.h> 2 #include <unistd.h> 3 #include <fcntl.h> 4 5 main() 6 { 7 struct iovec uiop[3]; 8 void *addr1, *addr2, *addr3; 9 int fd, nbytes; 10 11 addr1 = (void *)malloc(4096); 12 addr2 = (void *)malloc(4096); 13 addr3 = (void *)malloc(4096); 14 15 uiop[0].iov_base = addr1; uiop[0].iov_len ...

Get UNIX Filesystems: Evolution, Design, and Implementation now with the O’Reilly learning platform.

O’Reilly members experience live online training, plus books, videos, and digital content from nearly 200 publishers.