В 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
.Эта комбинация, возможно, не самая эффективная, но она хорошо документирована и работает как документированная .