What Is the Status of Posix Asynchronous I/O (Aio)

What is the status of POSIX asynchronous I/O (AIO)?

Network I/O is not a priority for AIO because everyone writing POSIX network servers uses an event based, non-blocking approach. The old-style Java "billions of blocking threads" approach sucks horribly.

Disk write I/O is already buffered and disk read I/O can be prefetched into buffer using functions like posix_fadvise. That leaves direct, unbuffered disk I/O as the only useful purpose for AIO.

Direct, unbuffered I/O is only really useful for transactional databases, and those tend to write their own threads or processes to manage their disk I/O.

So, at the end that leaves POSIX AIO in the position of not serving any useful purpose. Don't use it.

Difference between POSIX AIO and libaio on Linux?

On linux, the two AIO implementations are fundamentally different.

The POSIX AIO is a user-level implementation that performs normal blocking I/O in multiple threads, hence giving the illusion that the I/Os are asynchronous. The main reason to do this is that:

  1. it works with any filesystem
  2. it works (essentially) on any operating system (keep in mind that gnu's libc is portable)
  3. it works on files with buffering enabled (i.e. no O_DIRECT flag set)

The main drawback is that your queue depth (i.e. the number of outstanding operations you can have in practice) is limited by the number of threads you choose to have, which also means that a slow operation on one disk may block an operation going to a different disk. It also affects which I/Os (or how many) is seen by the kernel and the disk scheduler as well.

The kernel AIO (i.e. io_submit() et.al.) is kernel support for asynchronous I/O operations, where the io requests are actually queued up in the kernel, sorted by whatever disk scheduler you have, presumably some of them are forwarded (in somewhat optimal order one would hope) to the actual disk as asynchronous operations (using TCQ or NCQ). The main restriction with this approach is that not all filesystems work that well or at all with async I/O (and may fall back to blocking semantics), files have to be opened with O_DIRECT which comes with a whole lot of other restrictions on the I/O requests. If you fail to open your files with O_DIRECT, it may still "work", as in you get the right data back, but it probably isn't done asynchronously, but is falling back to blocking semantics.

Also keep in mind that io_submit() can actually block on the disk under certain circumstances.

AIO Asynchronous I/O with a callback function -- looking for best way

Answering question #2, simply define a data structure into which you store the additional data you need, and set sival_ptr to that. For example:

struct my_data {
struct aiocb cb;

// For demonstration's sake:
int foo;
char *bar;
size_t quux;
}

// ...

struct my_data data;
data.cb.aio_sigevent.sigev_value.sival_ptr = &data;
// Setup the rest of the struct and execute the read.

In the callback, you have access to the my_data struct now.

Linux aio (not posix) examples?

Update: this shows an example for the native linux io interface

(This is an example on the posix aio interface).

As to some of the commentters on the question: the aio library allows a program to issue multiple parallel request in a way where the kernel can execute them in the order which is most efficient for seeks and disk rotation -- i.e. the io request may not be executed in the order which they were issues which is different from making synchronous request in a thread. In very IO intensive applications this can dramatically increase IO performance, but for most applications it will just add complexity.



Related Topics



Leave a reply



Submit