Linux AIO Mechanism

Source: Internet
Author: User

Linux AIO Mechanism

Linux's I/O mechanism has gone through several stages of evolution:
1. synchronous blocking I/O: User processes perform I/O operations until the I/O operations are completed.
2. Non-blocking I/O synchronization: the user program can set the O_NONBLOCK attribute of the file descriptor, and the I/O operation can return immediately, but it does not guarantee that the I/O operation is successful.
3. asynchronous event blocking I/O: User processes can block I/O events, but I/O operations are not blocked. This is achieved through function calls such as select/poll/epoll.
4. asynchronous time non-blocking I/O: Also called asynchronous I/O (AIO), the user program can send an I/O Request command to the kernel, you do not need to wait for an I/O event to actually occur. You can continue to do other things. After I/O operations are completed, the kernel will notify the user of the process through function callback or signal mechanism. This greatly increases the system throughput.

The following describes AIO in detail:
To use the aio function, you need to include the header file aio. h. when compiling the connection, you need to add the POSIX real-time extension library rt. The following describes the use of the aio library.
1. The data used in the AIO process is stored in a struct, struct aiocb and aio control block. Let's see the definition in the header file:

/* Asynchronous I/O control block .*/
Struct aiocb
{
Int aio_fildes;/* File desriptor. */specifies the File descriptor on which I/O is required.
Int aio_lio_opcode;/* Operation to be performed med. */This is effective for Batch I/O operations.
Int aio_reqprio;/* Request priority offset. */Request priority (If _ POSIX_PRIORITIZED_IO is defined, and this file supports it, then
Asynchronous operation is submitted at a priority equal to that of
Calling process minus aiowhite-> aio_reqprio .)
Volatile void * aio_buf;/* Location of buffer. */specific content, data cache
Size_t aio_nbytes;/* Length of transfer. */data cache Length
Struct sigevent aio_sigevent;/* Signal number and value. */is used for notifications after asynchronous I/O is complete.

Data members used internally.
/* Internal members .*/
Struct aiocb * _ next_prio;
Int _ abs_prio;
Int _ policy;
Int _ error_code;
_ Ssize_t _ return_value;

# Ifndef _ USE_FILE_OFFSET64
_ Off_t aio_offset;/* File offset .*/
Char _ pad [sizeof (_ off64_t)-sizeof (_ off_t)];
# Else
_ Off64_t aio_offset;/* File offset. */File read/write offset
# Endif
Char _ unused [32];
};

2. int aio_read (struct aiocb * aiocbp );
The asynchronous read operation sends a READ command to the kernel. The input parameter is an aiocb structure, such
Struct aiocb myaiocb;
Memset (& aiocb, 0x00, sizeof (myaiocb ));
Myaiocb. aio_fildes = fd;
Myaiocb. aio_buf = new char [2, 1024];
Myaiocb. aio_nbytes = 1024;
If (aio_read (& myaiocb )! = 0)
{
Printf ("aio_read error: % s/n", strerror (errno ));
Return false;
}

3. int aio_write (struct aiocb * aiocbp );
Asynchronous write operations send write commands to the kernel. The input parameter is still an aiocb structure. When the file descriptor's O_APPEND
After the flag is set, asynchronous write operations always add data to the end of the file. If no value is set, add it to the specified aio_offset
Such:
Struct aiocb myaiocb;
Memset (& aiocb, 0x00, sizeof (myaiocb ));
Myaiocb. aio_fildes = fd;
Myaiocb. aio_buf = new char [2, 1024];
Myaiocb. aio_nbytes = 1024;
Myaiocb. aio_offset = 0;
If (aio_write (& myaiocb )! = 0)
{
Printf ("aio_read error: % s/n", strerror (errno ));
Return false;
}

4. int aio_error (const struct aiocb * aiocbp );
If this function returns 0, it indicates that the asynchronous I/O operation request specified by aiocbp is completed.
If this function returns EINPROGRESS, it indicates that the asynchronous I/O operation request specified by aiocbp is being processed.
If this function returns ECANCELED, it indicates that the asynchronous I/O operation request specified by aiocbp has been canceled.
If the function returns-1, an error occurs. Check errno.

5. ssize_t aio_return (struct aiocb * aiocbp );
The return value of this function is equivalent to the read/write return value in synchronous I/O. Only after aio_error is called
To be called.

6. int aio_cancel (int fd, struct aiocb * aiocbp );
Cancels the asynchronous I/O Request specified by aiocbp on the file descriptor fd.
If this function returns AIO_CANCELED, the operation is successful.
If the function returns AIO_NOTCANCELED, the cancellation operation is unsuccessful. Use aio_error to check the status.
If-1 is returned, an error occurs. Check errno.

7. int lio_listio (int mode, struct aiocb * restrict const list [restrict],
Int nent, struct sigevent * restrict sig );
Using this function can greatly improve the system performance, because the OS needs to perform
If we place more I/O operations in one switch between user mode and kernel mode,
Reduce the number of switching times. In other words, do as much as possible in the kernel. This improves the system performance.

The user program provides an array of struct aiocb. Each element represents an AIO request. Struct aiocb needs to be set
Value of the aio_lio_opcode data member in, including LIO_READ, LIO_WRITE, and LIO_NOP.
Nent indicates the number of elements in the array. The last parameter is the setting of the notification mechanism after the AIO operation is completed.

8. Set the AIO notification mechanism. There are two notification mechanisms: Signal and callback.
(1). Signal Mechanism
First, we should capture the SIGIO signal and process it:
Struct sigaction sig_act;
Sigempty (& sig_act.sa_mask );
Sig_act.sa_flags = SA_SIGINFO;
Sig_act.sa_sigaction = aio_handler;

Struct aiocb myaiocb;
Bzero (char *) & myaiocb, sizeof (struct aiocb ));
Myaiocb. aio_fildes = fd;
Myaiocb. aio_buf = malloc (BUF_SIZE + 1 );
Myaiocb. aio_nbytes = BUF_SIZE;
Myaiocb. aio_offset = next_offset;

Myaiocb. aio_sigevent.sigev_notify = SIGEV_SIGNAL;
Myaiocb. aio_sigevent.sigev_signo = SIGIO;
Myaiocb. aio_sigevent.sigev_value.sival_ptr = & myaiocb;

Ret = sigaction (SIGIO, & sig_act, NULL );

Implementation of signal processing functions:
Void aio_handler (int signo, siginfo_t * info, void * context)
{
Struct aiocb * req;

If (info-> si_signo = SIGIO ){
Req = (struct aiocb *) info-> si_value.sival_ptr;

If (aio_error (req) = 0 ){
Ret = aio_return (req );
}
}
Return;
}

(2). callback mechanism
You need to set:
Myaiocb. aio_sigevent.sigev_policy = SIGEV_THREAD
My_aiocb.aio_sigevent.policy_function = aio_handler;

Callback function prototype:
Typedef void (* FUNC_CALLBACK) (sigval_t sigval );

The AIO Mechanism provides a means to optimize the performance of highly concurrent applications on the server side. Increased system throughput.

This article permanently updates the link address:

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.