天天看點

linux異步IO--aio linux異步通知

簡述

linux下異步方式有兩種:異步通知和異步IO(AIO),異步通知請參考:linux異步通知

Linux的I/O機制經曆了一下幾個階段的演進:

1. 同步阻塞I/O: 使用者程序進行I/O操作,一直阻塞到I/O操作完成為止。

2. 同步非阻塞I/O: 使用者程式可以通過設定檔案描述符的屬性O_NONBLOCK,I/O操作可以立即傳回,但是并不保證I/O操作成功。

3. 異步事件阻塞I/O: 使用者程序可以對I/O事件進行阻塞,但是I/O操作并不阻塞。通過select/poll/epoll等函數調用來達到此目的。

4. 異步時間非阻塞I/O: 也叫做異步I/O(AIO),使用者程式可以通過向核心發出I/O請求指令,不用等待I/O事件真正發生,可以繼續做另外的事情,等I/O操作完成,核心會通過函數回調或者信号機制通知使用者程序。這樣很大程度提高了系統吞吐量。

linux異步IO--aio linux異步通知

The POSIX asynchronous I/O (AIO) interface allows applications to initiate one or more I/O operations that are performed asynchronously (i.e., in the background).

The application can elect to be notified of completion of the I/O operation in a variety of ways: by delivery of a signal, by instantiation of a thread, or no notification at all.

函數

The POSIX AIO interface consists of the following functions:

aio_read(3) Enqueue a read request. This is the asynchronous analog of read(2).

aio_write(3) Enqueue a write request. This is the asynchronous analog of write(2).

aio_fsync(3) Enqueue a sync request for the I/O operations on a file descriptor. This is the asynchronous analog of fsync(2) and fdatasync(2).

aio_error(3) Obtain the error status of an enqueued I/O request.

aio_return(3) Obtain the return status of a completed I/O request.

aio_suspend(3) Suspend the caller until one or more of a specified set of I/O requests completes.

aio_cancel(3) Attempt to cancel outstanding I/O requests on a specified file descriptor.

lio_listio(3) Enqueue multiple I/O requests using a single function call.

在異步非阻塞IO中,可以同時發起多個傳輸操作。這需要每個傳輸操作有唯一的上下文,這樣才能在它們完成時區分到底是哪個傳輸操作完成了。在AIO中通過aiocb(AIO I/O control Block)結構體區分。

aiocb包含了有關傳輸的所有資訊,以及為資料準備的使用者緩沖區。在産生I/O通知(完成)時,aiocb結構就被用來唯一辨別所完成的I/O操作。

#include <aiocb.h>

           struct aiocb {
               /* The order of these fields is implementation-dependent */

               int             aio_fildes;     /* File descriptor */
               off_t           aio_offset;     /* File offset */
               volatile void  *aio_buf;        /* Location of buffer */
               size_t          aio_nbytes;     /* Length of transfer */
               int             aio_reqprio;    /* Request priority */
               struct sigevent aio_sigevent;   /* Notification method */
               int             aio_lio_opcode; /* Operation to be performed;
                                                  lio_listio() only */

               /* Various implementation-internal fields not shown */
           };

           /* Operation codes for 'aio_lio_opcode': */

           enum { LIO_READ, LIO_WRITE, LIO_NOP };      

The fields of this structure are as follows:

aio_filedes The file descriptor on which the I/O operation is to be performed.

aio_offset This is the file offset at which the I/O operation is to be performed.

aio_buf This is the buffer used to transfer data for a read or write operation.

aio_nbytes This is the size of the buffer pointed to by aio_buf.

aio_reqprio This field specifies a value that is subtracted from the calling thread's real-time priority in order to determine the priority for execution of this I/O request(see pthread_setschedparam(3)). The specified value must be between 0 and the value returned by sysconf(_SC_AIO_PRIO_DELTA_MAX). This field is ignored for file synchronization operations.

aio_sigevent This field is a structure that specifies how the caller is to be notified when the asynchronous I/O operation completes. Possible values for aio_sigevent.sigev_notify are SIGEV_NONE, SIGEV_SIGNAL, and SIGEV_THREAD. See sigevent(7) for further details.

aio_lio_opcode The type of operation to be performed; used only for lio_listio(3).

應用

應用主要有兩種方式:信号機制和回調函數。

繼續閱讀