Эффективное выполнение ввода-вывода сокетов решено с помощью kqueue, epoll, портов завершения ввода-вывода и т.п. Выполнение асинхронного файлового ввода-вывода - это своего рода поздний этап (помимо перекрывающегося ввода-вывода Windows и ранней поддержки posix AIO в Solaris).
Если вы ищете возможность ввода-вывода через сокеты, вам, вероятно, лучше использовать один из вышеперечисленных механизмов.
Таким образом, основная цель AIO - решить проблему асинхронного дискового ввода-вывода. Скорее всего, поэтому Mac OS X поддерживает только AIO для обычных файлов, а не сокетов (поскольку kqueue в любом случае делает это намного лучше).
Операции записи обычно кэшируются ядром и удаляются позже. Например, когда считывающая головка привода проходит мимо места, где должен быть записан блок.
Однако для операций чтения, если вы хотите, чтобы ядро расставляло приоритеты и упорядочивало чтение, AIO - действительно единственный вариант. Вот почему ядро может (теоретически) делать это лучше, чем любое приложение пользовательского уровня:
- Ядро видит все дисковые операции ввода-вывода, а не только дисковые задания ваших приложений, и может упорядочить их на глобальном уровне.
- Ядро (может) знать, где находится считывающая головка диска, и может выбирать задания чтения, которые вы передаете ему в оптимальном порядке, чтобы переместить головку на кратчайшее расстояние.
- Ядро может использовать встроенную очередь команд для дальнейшей оптимизации операций чтения.
- Вы можете выполнять больше операций чтения для одного системного вызова с помощью lio_listio (), чем с readv (), особенно если ваши чтения не (логически) непрерывны, что позволяет сэкономить небольшой кусок служебных данных системного вызова.
- Ваша программа может быть немного проще с AIO, поскольку вам не нужен дополнительный поток для блокировки при вызове чтения или записи.
Тем не менее, posix AIO имеет довольно неудобный интерфейс, например:
- Единственное эффективное и хорошо поддерживаемое средство обратных вызовов событий - это сигналы, что затрудняет использование в библиотеке, поскольку это означает использование номеров сигналов из глобального пространства имен сигналов. Если ваша ОС не поддерживает сигналы в реальном времени, это также означает, что вам нужно перебрать все невыполненные запросы, чтобы выяснить, какой из них на самом деле завершен (это, например, Mac OS X, а не Linux). Улавливание сигналов в многопоточной среде также накладывает некоторые хитрые ограничения. Обычно вы не можете реагировать на событие внутри обработчика сигнала, но вы должны поднять сигнал, записать в канал или использовать signalfd () (в Linux).
- lio_suspend () имеет те же проблемы, что и select (), он не очень хорошо масштабируется с количеством заданий.
- lio_listio () в том виде, в котором она реализована, имеет довольно ограниченное количество заданий, которые вы можете передать, и найти это ограничение переносимым способом нетривиально. Вы должны вызвать sysconf (_SC_AIO_LISTIO_MAX), который может дать сбой, и в этом случае вы можете использовать определение AIO_LISTIO_MAX, которое не обязательно определено, но затем вы можете использовать 2, который определен как гарантированно поддерживаемый.
Что касается реального приложения, использующего posix AIO, вы можете взглянуть на lighttpd (lighty), который также опубликовал измерение производительности при представлении поддержки.
Большинство платформ posix на данный момент поддерживают posix AIO (Linux, BSD, Solaris, AIX, tru64). Windows поддерживает его через перекрывающийся файловый ввод-вывод. Насколько я понимаю, только Solaris, Windows и Linux действительно поддерживают асинхронность. файловый ввод-вывод вплоть до драйвера, тогда как другие ОС эмулируют асинхронный режим. Ввод-вывод с потоками ядра. Linux является исключением, его реализация posix AIO в glibc эмулирует асинхронные операции с потоками пользовательского уровня, тогда как его собственный интерфейс асинхронного ввода-вывода (io_submit () и т. Д.) Действительно асинхронен на всем пути вплоть до драйвера, если драйвер поддерживает его. .
Я считаю, что среди операционных систем довольно распространено не поддерживать posix AIO для любого fd, а ограничивать его обычными файлами.