Эффективное выполнение сокетного ввода-вывода было решено с помощью kqueue, epoll, портов завершения ввода-вывода и тому подобного. Выполнение асинхронного файлового ввода-вывода является своего рода поздним приходом (кроме перекрывающегося ввода-вывода Windows и ранней поддержки Solaris для posix AIO).
Если вы ищете возможность ввода / вывода через сокет, вам, вероятно, лучше использовать один из перечисленных выше механизмов.
Следовательно, основной целью AIO является решение проблемы асинхронного дискового ввода-вывода. Скорее всего, именно поэтому Mac OS X поддерживает AIO только для обычных файлов, а не для сокетов (поскольку kqueue делает это намного лучше).
Операции записи обычно кэшируются ядром и сбрасываются позднее. Например, когда считывающая головка привода проходит мимо места, где должен быть записан блок.
Однако, для операций чтения, если вы хотите, чтобы ядро расставило приоритеты и упорядочило ваши чтения, AIO - действительно единственная опция. Вот почему Kernal (теоретически) может сделать это лучше, чем любое приложение уровня пользователя:
- Ядро видит все дисковые операции ввода-вывода, а не только задания дисков ваших приложений, и может упорядочить их на глобальном уровне
- Ядро (может) знает, где находится головка чтения диска, и может выбрать задания чтения, которые вы передаете ей в оптимальном порядке, чтобы переместить головку на кратчайшее расстояние
- Ядро может использовать преимущества собственной очереди команд для дальнейшей оптимизации операций чтения
- Вы можете выполнить больше операций чтения на системный вызов с помощью 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, но ограничить его обычными файлами.