Advanced Programming in the UNIX® Environment

(lily) #1
ptg10805159

Section 14.5 Asynchronous I/O 509


None of the implementations described in this book restartpollorselectwhen a signal is
received, even if theSA_RESTARTflag is used.

14.5 Asynchronous I/O


Usingselectandpoll, as described in the previous section, is a synchronous form of
notification. The system doesn’t tell us anything until we ask (by calling eitherselect
or poll). As we saw in Chapter 10, signals provide an asynchronous form of
notification that something has happened. All systems derived from BSD and System V
provide some form of asynchronous I/O, using a signal (SIGPOLLin System V;SIGIO
in BSD) to notify the process that something of interest has happened on a descriptor.
As mentioned in the previous section, these forms of asynchronous I/O arelimited:
they don’t work with all file types and they allow the use of only one signal. If we
enable morethan one descriptor for asynchronous I/O, we cannot tell which descriptor
the signal corresponds to when the signal is delivered.
Version 4 of the Single UNIX Specification moved the general asynchronous I/O
mechanism from the real-time extensions to the base specification. This mechanism
addresses the limitations that exist with these older asynchronous I/O facilities.
Before we look at the different ways to use asynchronous I/O, we need to discuss
the costs. When we decide to use asynchronous I/O, we complicate the design of our
application by choosing to juggle multiple concurrent operations.Asimpler approach
may be to use multiple threads, which would allow us to write the program using a
synchronous model, and let the threads run asynchronous to each other.
We incur additional complexity when we use the POSIX asynchronous I/O
interfaces:

•Wehave to worry about three sources of errors for every asynchronous
operation: one associated with the submission of the operation, one associated
with the result of the operation itself, and one associated with the functions used
to determine the status of the asynchronous operations.
•The interfaces themselves involve a lot of extra setup and processing rules
compared to their conventional counterparts, as we shall see.

We can’t really call the non-asynchronous I/O function calls ‘‘synchronous,’’because
although they aresynchronous with respect to the program flow,they aren’t
synchronous with respect to the I/O. Recall the discussion of synchronous writes in
Chapter 3.We call a write ‘‘synchronous’’ if the data we write is persistent when we
return from the call to thewritefunction. Wealso can’t differentiate the
conventional I/O function calls from the asynchronous ones by referring to the
conventional calls as the ‘‘standard’’I/O calls, because this confuses them with the
function calls in the standardI/O library.Toavoid confusion, we’ll refer to the
readandwritefunctions as the ‘‘conventional’’I/O function calls in this section.

•Recovering from errors can be difficult. For example, if we submit multiple
asynchronous writes and one fails, how should we proceed? If the writes are
related, we might have to undo the ones that succeeded.
Free download pdf