The Linux Programming Interface

(nextflipdebug5) #1
Alternative I/O Models 1327

Because of the limitations of both nonblocking I/O and the use of multiple
threads or processes, one of the following alternatives is often preferable:


z I/O multiplexing allows a process to simultaneously monitor multiple file descrip-
tors to find out whether I/O is possible on any of them. The select() and poll()
system calls perform I/O multiplexing.


z Signal-driven I/O is a technique whereby a process requests that the kernel send
it a signal when input is available or data can be written on a specified file
descriptor. The process can then carry on performing other activities, and is
notified when I/O becomes possible via receipt of the signal. When monitor-
ing large numbers of file descriptors, signal-driven I/O provides significantly
better performance than select() and poll().


z The epoll API is a Linux-specific feature that first appeared in Linux 2.6. Like
the I/O multiplexing APIs, the epoll API allows a process to monitor multiple
file descriptors to see if I/O is possible on any of them. Like signal-driven I/O,
the epoll API provides much better performance when monitoring large num-
bers of file descriptors.


In the remainder of this chapter, we’ll generally frame the discussion of the
above techniques in terms of processes. However, these techniques can also be
employed in multithreaded applications.

In effect, I/O multiplexing, signal-driven I/O, and epoll are all methods of achiev-
ing the same result—monitoring one or, commonly, several file descriptors simulta-
neously to see if they are ready to perform I/O (to be precise, to see whether an I/O
system call could be performed without blocking). The transition of a file descrip-
tor into a ready state is triggered by some type of I/O event, such as the arrival of
input, the completion of a socket connection, or the availability of space in a previ-
ously full socket send buffer after TCP transmits queued data to the socket peer.
Monitoring multiple file descriptors is useful in applications such as network serv-
ers that must simultaneously monitor multiple client sockets, or applications that
must simultaneously monitor input from a terminal and a pipe or socket.
Note that none of these techniques performs I/O. They merely tell us that a
file descriptor is ready. Some other system call must then be used to actually per-
form the I/O.


One I/O model that we don’t describe in this chapter is POSIX asynchronous
I/O (AIO). POSIX AIO allows a process to queue an I/O operation to a file
and then later be notified when the operation is complete. The advantage of
POSIX AIO is that the initial I/O call returns immediately, so that the process
is not tied up waiting for data to be transferred to the kernel or for the opera-
tion to complete. This allows the process to perform other tasks in parallel
with the I/O (which may include queuing further I/O requests). For certain
types of applications, POSIX AIO can provide useful performance benefits.
Currently, Linux provides a threads-based implementation of POSIX AIO
within glibc. At the time of writing, work is ongoing toward providing an in-ker-
nel implementation of POSIX AIO, which should provide better scaling per-
formance. POSIX AIO is described in [Gallmeister, 1995] and [Robbins &
Robbins, 2003].
Free download pdf