Каков статус асинхронного ввода-вывода POSIX (AIO)?
есть страницы, разбросанные по всему интернету, которые описывают объекты POSIX AIO в различной степени детализации. Ни один из них не очень свежие. Непонятно, что именно они описывают. Например, "чиновник" (?)веб-сайт для поддержки асинхронного ввода-вывода ядра Linux здесь говорит, что сокеты не работают, но "aio.H " страницы руководства на моей рабочей станции Ubuntu 8.04.1 все, кажется, подразумевают, что он работает для произвольных дескрипторов файлов. То есть другой проект, который, кажется, работает на уровне библиотеки С еще меньшим количеством документации.
Я хотел бы знать:
- какова цель POSIX AIO? Учитывая, что самый очевидный пример реализации, который я могу найти, говорит, что он не поддерживает сокеты, все это кажется мне странным. Это только для асинхронного дискового ввода-вывода? Если да, то почему гипер-общий API? Если нет, то почему дисковый ввод-вывод-это первое, что было атаковано?
- где есть пример полное POSIX AIO программы, которые я могу посмотреть?
- кто-нибудь действительно использует его, по-настоящему?
- какие платформы поддерживают POSIX AIO? Какие его части они поддерживают? Кто-нибудь действительно поддерживает подразумеваемый "любой ввод-вывод для любого FD", что
<aio.h>вроде как обещают?
4 ответов:
сетевой ввод-вывод не является приоритетом для AIO, потому что все пишущие сетевые серверы POSIX используют основанный на событиях, неблокирующий подход. Подход старого стиля Java "миллиарды блокирующих потоков" ужасно отстой.
дисковый ввод-вывод уже буферизован, а дисковый ввод-вывод чтения может быть предварительно установлен в буфер с помощью таких функций, как posix_fadvise. Это оставляет прямой, небуферизованный дисковый ввод-вывод в качестве единственной полезной цели для AIO.
прямой, небуферизованный ввод / вывод действительно полезен только для транзакционные базы данных, и те, как правило, пишут свои собственные потоки или процессы для управления своим дисковым вводом-выводом
Итак, в конце концов, что оставляет POSIX AIO в положении не служит любой полезной цели. Не используй его.
эффективное выполнение сокета ввода/вывода было решено с помощью портов завершения kqueue, epoll, IO и подобных. Выполнение асинхронного ввода-вывода файлов является своего рода поздним пришельцем (помимо перекрывающегося ввода-вывода windows и ранней поддержки solaris для posix AIO).
Если вы ищете выполнение ввода-вывода сокета, вам, вероятно, лучше использовать один из вышеперечисленных механизмов.
основная цель AIO, следовательно, чтобы решить проблему асинхронного дискового ввода-вывода это, скорее всего, почему Mac OS X только поддерживает AIO для обычных файлов, а не сокетов (так как kqueue делает это намного лучше в любом случае).
операции записи обычно кэшируются ядром и удаляются позднее. Например, когда считывающая головка диска проходит мимо места, где блок должен быть записан.
однако для операций чтения, если вы хотите, чтобы ядро определяло приоритеты и упорядочивало ваши чтения, AIO действительно является единственным вариантом. Вот почему ядро может (теоретически) сделать это лучше, чем любое приложение пользовательского уровня:
- ядро видит все дисковые операции ввода-вывода, а не только ваши приложения дисковых заданий, и может заказать их на глобальном уровне
- ядро (может) знать, где находится головка чтения диска, и может выбрать задания чтения, которые вы передаете ему в оптимальном порядке, чтобы переместить головку на самое короткое расстояние
- ядро может воспользоваться родная организация очереди команды для оптимизации операций чтения дальше
- вы можете выполнить больше операций чтения для каждого системного вызова с помощью lio_listio(), чем с помощью readv (), особенно если ваши чтения не являются (логически) непрерывными, экономя немного накладных расходов системного вызова.
- ваша программа может быть немного проще с AIO, так как вам не нужен дополнительный поток для блокировки в вызове чтения или записи.
тем не менее, posix AIO имеет довольно неудобный интерфейс, например:
- только эффективное и хорошо поддерживаемое средство обратных вызовов событий осуществляется через сигналы, что затрудняет его использование в библиотеке, поскольку это означает использование номеров сигналов из пространства имен process-global signal. Если ваша ОС не поддерживает сигналы в реальном времени, это также означает, что вам нужно перебрать все ваши невыполненные запросы, чтобы выяснить, какой из них фактически завершен (это относится, например, к Mac OS X, а не к Linux). Улавливание сигналов в многопоточной среде также создает некоторые сложные ограничения. Вы обычно не может реагировать на событие внутри обработчика сигнала, но вы должны поднять сигнал, записать в канал или использовать signalfd() (в linux).
- lio_suspend () имеет те же проблемы, что и select (), он не очень хорошо масштабируется с количеством заданий.
- lio_listio (), поскольку реализовано довольно ограниченное количество заданий, которые вы можете передать, и нетривиально найти этот предел переносимым способом. Вы должны вызвать sysconf (_SC_AIO_LISTIO_MAX), который может потерпеть неудачу, и в этом случае вы можете использовать aio_listio_max define, которые не обязательно определены, но затем вы можете использовать 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, но ограничивают его обычными файлами.
разработчик libtorrent предоставляет отчет об этом:http://blog.libtorrent.org/2012/10/asynchronous-disk-io/
в glibc реализован aio_write; первый вызов функции aio_read или aio_write порождает несколько потоков пользовательского режима, запросы aio_write или aio_read post к этому потоку, поток выполняет pread / pwrite, и когда он закончен, ответ отправляется обратно в заблокированный вызывающий поток.
там тоже "реальный" ОКН - поддерживает на уровне ядра (необходимо наличие библиотеки libaio для этого, увидеть io_submit вызов http://linux.die.net/man/2/io_submit ); также необходимо под д ержка для этого (также может не поддерживаться всеми файловыми системами, но основные из них поддерживают:)
смотрите здесь:
http://lse.sourceforge.net/io/aio.html
Comments