Updated: 2022/Sep/29

Please read Privacy Policy. It's for your privacy.

AIO(3)                     Library Functions Manual                     AIO(3)

     aio - asynchronous I/O (REALTIME)

     POSIX Real-time Library (librt, -lrt)

     #include <aio.h>

     The IEEE Std 1003.1-2001 ("POSIX.1") standard defines an interface for
     asynchronous input and output.  Although in NetBSD this is provided as
     part of the POSIX Real-time Library (librt, -lrt), the implementation
     largely resides in the kernel.

     The rationale can be roughly summarized with the following points.

       1.   To increase performance by providing a mechanism to carry out I/O
            without blocking.  Theoretically, if I/O would never block,
            neither at the software nor at the hardware level, the overhead of
            I/O would become zero, and processes would no longer be I/O bound.

       2.   To segregate the different I/O operations into logically
            distinctive procedures.  Unlike with the standard stdio(3), the
            aio interface separates queuing and submitting I/O operations to
            the kernel, and receiving notifications of operation completion
            from the kernel.

       3.   To provide an uniform and standardized framework for asynchronous
            I/O.  For instance, aio avoids the need for (and the overhead of)
            extra worker threads sometimes used to perform asynchronous I/O.

   Asynchronous I/O Control Block
     The Asynchronous I/O Control Block is the basic operational unit behind
     aio.  This is required since an arbitrary number of operations can be
     started at once, and because each operation can be either input or
     output.  This block is represented by the aiocb structure, which is
     defined in the <aio.h> header.  The following fields are available for
     user applications:

           off_t            aio_offset;
           void            *aio_buf;
           size_t           aio_nbytes;
           int              aio_fildes;
           int              aio_lio_opcode;
           int              aio_reqprio;
           struct sigevent  aio_sigevent;

     The fields are:

           1.   The aio_offset specifies the implicit file offset at which the
                I/O operations are performed.  This cannot be expected to be
                the actual read/write offset of the file descriptor.

           2.   The aio_buf member is a pointer to the buffer to which data is
                going to be written or to which the read operation stores

           3.   The aio_nbytes specifies the length of aio_buf.

           4.   The aio_fildes specifies the used file descriptor.

           5.   The aio_lio_opcode is used by the lio_listio() function to
                initialize a list of I/O requests with a single call.

           6.   The aio_reqprio member can be used to lower the scheduling
                priority of an aio operation.  This is only available if
                defined, and the associated file descriptor supports it.

           7.   The aio_sigevent member is used to specify how the calling
                process is notified once an aio operation completes.

     The members aio_buf, aio_fildes, and aio_nbytes are conceptually similar
     to the parameters `buf', `fildes', and `nbytes' used in the standard
     read(2) and write(2) functions.  For example, the caller can read
     aio_nbytes from a file associated with the file descriptor aio_fildes
     into the buffer aio_buf.  All appropriate fields should be initialized by
     the caller before aio_read() or aio_write() is called.

   File Offsets
     Asynchronous I/O operations are not strictly sequential; operations are
     carried out in arbitrary order and more than one operation for one file
     descriptor can be started.  The requested read or write operation starts
     from the absolute position specified by aio_offset, as if lseek(2) would
     have been called with SEEK_SET immediately prior to the operation.  The
     POSIX standard does not specify what happens after an aio operation has
     been successfully completed.  Depending on the implementation, the actual
     file offset may or may not be updated.

   Errors and Completion
     Asynchronous I/O operations are said to be complete when:

          An error is detected.

          The I/O transfer is performed successfully.

          The operation is canceled.

     If an error condition is detected that prevents an operation from being
     started, the request is not enqueued.  In this case the read and write
     functions, aio_read() and aio_write(), return immediately, setting the
     global errno to indicate the cause of the error.

     After an operation has been successfully enqueued, aio_error() and
     aio_return() must be used to determine the status of the operation and to
     determine any error conditions.  This includes the conditions reported by
     the standard read(2), write(2), and fsync(2).  The request remains
     enqueued and consumes process and system resources until aio_return() is

   Waiting for Completion
     The aio interface supports both polling and notification models.  The
     first can be implemented by simply repeatedly calling the aio_error()
     function to test the status of an operation.  Once the operation has
     completed, aio_return() is used to free the aiocb structure for re-use.

     The notification model is implemented by using the aio_sigevent member of
     the Asynchronous I/O Control Block.  The operational model and the used
     structure are described in sigevent(3).

     The aio_suspend() function can be used to wait for the completion of one
     or more operations.  It is possible to set a timeout so that the process
     can continue the execution and take recovery actions if the aio
     operations do not complete as expected.

   Cancellation and Synchronization
     The aio_cancel() function can be used to request cancellation of an
     asynchronous I/O operation.  Note however that not all of them can be
     canceled.  The same aiocb used to start the operation may be used as a
     handle for identification.  It is also possible to request cancellation
     of all operations pending for a file.

     Comparable to fsync(2), the aio_fsync() function can be used to
     synchronize the contents of permanent storage when multiple asynchronous
     I/O operations are outstanding for the file or device.  The
     synchronization operation includes only those requests that have already
     been successfully enqueued.

     The following functions comprise the API of the aio interface:

           Function        Description
           aio_cancel(3)   cancel an outstanding asynchronous I/O operation
           aio_error(3)    retrieve error status of asynchronous I/O operation
           aio_fsync(3)    asynchronous data synchronization of file
           aio_read(3)     asynchronous read from a file
           aio_return(3)   get return status of asynchronous I/O operation
           aio_suspend(3)  suspend until operations or timeout complete
           aio_write(3)    asynchronous write to a file
           lio_listio(3)   list directed I/O

     Unfortunately, the POSIX asynchronous I/O implementations vary slightly.
     Some implementations provide a slightly different API with possible
     extensions.  For instance, the FreeBSD implementation uses a function
     `aio_waitcomplete()' to wait for the next completion of an aio request.

     The aio interface is expected to conform to the IEEE Std 1003.1-2001
     ("POSIX.1") standard.

     The aio interface first appeared in NetBSD 5.0.

     Few limitations can be mentioned:

        Undefined behavior results if simultaneous asynchronous operations
         use the same Asynchronous I/O Control Block.

        When an asynchronous read operation is outstanding, undefined
         behavior may follow if the contents of aiocb are altered, or if
         memory associated with the structure, or the aio_buf buffer, is

NetBSD 10.99                     May 19, 2010                     NetBSD 10.99