Vectored I/O

This article is about the I/O method. For the vector addressing type, see Gather-scatter (vector addressing).

In computing, vectored I/O, also known as scatter/gather I/O, is a method of input and output by which a single procedure call sequentially reads data from multiple buffers and writes it to a single data stream, or reads data from a data stream and writes it to multiple buffers. The buffers are given in a vector of buffers. Scatter/gather refers to the process of gathering data from, or scattering data into, the given set of buffers. Vectored I/O can operate synchronously or asynchronously. The main reasons for using vectored I/O are efficiency and convenience.

There are several usages for vectored I/O:

Standards bodies document the applicable functions readv[1] and writev[2] in POSIX 1003.1-2001 and the Single UNIX Specification version 2. The Windows API has analogous functions ReadFileScatter and WriteFileGather; however, unlike the POSIX functions, they require the alignment of each buffer on a memory page.[3] Windows Sockets provide separate WSASend and WSARecv functions without this requirement.

While working directly with a vector of buffers can be significantly harder than working with a single buffer, there are often higher-level APIs[4] for working efficiently that can mitigate the problem.

Examples

The following example prints "Hello Wikipedia Community!" to the standard output. Each word is saved into a single buffer and with only one call to writev(), all buffers are printed to the standard output.

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

#include <sys/types.h>
#include <unistd.h>
#include <sys/uio.h>

#define NUMBUFS 3

int
main(int argc, char *argv[])
{
	const char *buf1 = "Hello ";
	const char *buf2 = "Wikipedia ";
	const char *buf3 = "Community!\n";

	struct iovec bufs[NUMBUFS];

	bufs[0].iov_base = (void*) buf1;
	bufs[0].iov_len = strlen(buf1);

	bufs[1].iov_base = (void*) buf2;
	bufs[1].iov_len = strlen(buf2);

	bufs[2].iov_base = (void*) buf3;
	bufs[2].iov_len = strlen(buf3);

	if (-1 == writev(STDOUT_FILENO, bufs, NUMBUFS))
	{
		perror("writev()");
		exit(EXIT_FAILURE);
	}

	return 0;
}

References

  1. readv in the Single Unix Specification
  2. writev in the Single Unix Specification
  3. ReadFileScatter in MSDN Library
  4. Vstr the Vectored String API
This article is issued from Wikipedia - version of the Tuesday, February 16, 2016. The text is available under the Creative Commons Attribution/Share Alike but additional terms may apply for the media files.