Поддержка AIO в Linux - PullRequest
       33

Поддержка AIO в Linux

2 голосов
/ 31 октября 2011

Кто-нибудь знает, где я могу получить актуальную информацию о состоянии поддержки ядра для aio в последней версии ядра Linux ?.Поиски в Google приводят к появлению веб-страниц, которые могут быть безнадежно устаревшими.

Редактировать:

В частности, меня интересуют дескрипторы, не связанные с файлами, такие как каналы и сокеты.Вещи в Интернете указывают на то, что поддержки нет, так ли это?

Edit2: я ищу что-то похожее на Windows OVERLAPPED IO

Ответы [ 3 ]

5 голосов
/ 31 октября 2011

Вам не нужен POSIX AIO (т.е. man aio) для асинхронного использования сокетов и каналов.Согласно man 3 aio это даже невозможно.Вместо этого следует использовать неблокирующие файловые дескрипторы вместе с интерфейсом уведомления о событии , таким как select(), poll() или epoll.epoll зависит от Linux, но масштабируется намного лучше, чем предыдущие два.

Чтобы использовать файловые дескрипторы в неблокирующем режиме, вы должны установить флаг O_NONBLOCK для каждого файлового дескриптора:

fcntl(fd, F_SETFL, O_NONBLOCK)

После того, как дескриптор файла находится в неблокирующем режиме, операции ввода-вывода, такие как read() и write(), никогда не будут блокироваться, но вернут EAGAIN или EWOULDBLOCK, если операция не может быть завершена немедленно.Некоторые более специфичные операции, такие как connect(), должны использоваться по-другому в неблокирующем режиме;см. соответствующие страницы руководства.

Чтобы правильно использовать неблокирующие дескрипторы файлов, ваше приложение должно быть управляемым событиями .По сути, в main() вам нужно сначала инициализировать материал, а затем войти в цикл событий .Цикл событий многократно ожидает события (используя интерфейс уведомления о событиях, например, epoll_wait()), затем проверяет, какие события произошли, и реагирует на них.

Теперь, когда вы говорите read(), и это не удаетсяс EWOULDBLOCK вы добавляете его в список файловых дескрипторов, отслеживаемых для удобства чтения;когда поставщик событий указывает на удобочитаемость, вы пытаетесь снова.

Аналогично, если вы пытаетесь write(), и он терпит неудачу с EWOULDBLOCK, вы можете захотеть буферизовать данные и повторить попытку, когда указана возможность записи.1037 *

4 голосов
/ 31 октября 2011

В Linux есть два вида AIO.

Один из них - ядро-AIO.Это некрасиво, а иногда не ведет себя в соответствии с документацией (например, оно будет работать синхронно при определенных условиях, если вы не сможете что-то с этим сделать, и не будет должным образом отменять запросы в полете при определенных условиях и т. Д.,так далее).Он не работает на каналах.
Это функции типа io_.Обратите внимание, что вы должны связать с -laio, который вы должны отдельно установить в некоторых системах (например, Debian / Ubuntu).

Второй вариант - это чисто пользовательская реализация (glibc), которая порождает потоки по требованию для обработки запросов.,Он хорошо документирован, работает достаточно хорошо и, согласно документации, работает практически со всем, что является файловым дескриптором , включая каналы .
. Это такие функции aio_.Я бы определенно рекомендовал использовать их, даже если они являются «uncool реализацией пользовательского пространства» - они прекрасно работают.

В то же время оба работают с eventfd в качестве механизма уведомления, кстати, хотя версия ядра былавсе еще недокументированный в прошлый раз, когда я смотрел (но функция в заголовках).

Или, как указал Амброз Бизжак, вообще пропустить AIO, поскольку то, что вы описываете, не является строго необходимым.

РЕДАКТИРОВАТЬ:
На другой ноте, так как вы использовали слова "трубы" и "розетки", знаете ли вы vmsplice и сращивания ?Это, вероятно, наиболее эффективные функции для отправки данных в / из сокетов / каналов.К сожалению, это еще один из этих неоднозначно задокументированных, трудно понять хаков с неясными подводными камнями.Действуйте на свой страх и риск, вас предупредили.

splice позволяет переносить данные из сокета (или любой дескриптор файла) в канал или наоборот.vmsplice позволяет передавать данные между областью приложения и каналом.
По иронии судьбы, vmsplice в идеале должен делать то же самое (переназначение страниц, или "играть с ВМ"), которое один конкретный человек воспринимал как аргументутверждают, что все разработчики BSD - идиоты, еще в 2006 году.

Итак, что касается хороших новостей, то плохая новость заключается в том, что существует «секретный предел» того, сколько данных вы можете перемещать.Насколько я помню, это 64 КБ (но настраивается где-то в / proc).Если у вас есть больше данных, чем это, вы должны поэтому работать в нескольких чанках, предположительно с несколькими конвейерными буферами, заполняя один, пока другой читается, и повторно используя старые конвейерные буферы после того, как они сделаны.
И это становится сложным,Просматривая обсуждения «Ядро ловушки», вы обнаружите, что даже Великий магистр не на 100% уверен в том, когда безопасно перезаписывать старый буфер при манипулировании несколькими буферами.

Также для vmsplice to на самом деле работа (т. Е. Переназначение страниц вместо копирования), вам нужно использовать флаг «ПОДАРОК», и, по крайней мере, мне не ясно из документации, что же тогда будет с этой памятью.Следуя документам к письму, вам может понадобиться утечка памяти, так как вам никогда не разрешат прикоснуться к ней снова.Конечно, этого не может быть.Может быть, я просто тупой.

Я в конце концов отказался от этого и просто согласился использовать epoll для готовности и неблокирующих сокетов с обычным нормальным write.Эта комбинация, возможно, не самая эффективная, но она хорошо документирована и работает как документированная .

2 голосов
/ 31 октября 2011

Поддержка AIO включена в собственно ядро ​​Linux.Вот почему первый хит в Google предлагает исправления только для ядра Linux 2.4.В 2.6 и 3.0 он уже там.

Если вы извлекаете исходный код ядра Linux, он находится по адресу fs / aio.c

В руководстве GNU libc имеется некоторая документация *1008*, но имейте в виду, что aio не возможно для всех типов файловых дескрипторов Linux.Большая часть общей документации по методике датирована примерно 2006 годом, что является уместным, поскольку именно тогда AIO в Linux делали заголовки.

Обратите внимание, что стандарты POSIX.1b и Unix98 приютилине изменились, так что вы можете быть немного конкретны в отношении природы "устаревших" примеров?

...