Состояние Linux асинхронного ввода-вывода? - PullRequest
10 голосов
/ 11 октября 2010

Я спрашиваю здесь, поскольку поиск в Google ведет вас в веселое путешествие по архивам без намека на то, каково текущее состояние. Если вы обращаетесь к Google, кажется, что асинхронный ввод-вывод был в моде в 2001-2003 годах, а к 2006 году появились такие вещи, как epoll и libaio; kevent появился, но, кажется, исчез, и, насколько я могу судить, до сих пор нет хорошего способа смешивания сигналов на основе завершения и на основе готовности, асинхронная sendfile - это вообще возможно ? - и все остальное в однопоточном цикле событий.

Так, пожалуйста, скажи мне, что я не прав, и все это радужно! - и, что важно, какие API использовать.

Как Linux в этом отношении сравнивается с FreeBSD и другими операционными системами?

Ответы [ 3 ]

4 голосов
/ 04 февраля 2011

AIO как таковой все еще несколько ограничен, и начинать с него очень сложно, но он работает, по большей части, после того, как вы его откопали.

У него есть некоторые, на мой взгляд, серьезныеошибки, но это действительно функции.Например, при отправке определенного количества команд или данных ваш поток будет заблокирован.Я не помню точного обоснования этой функции, но ответ, который я получил тогда, был что-то вроде: «Да, конечно, ядро ​​имеет ограничение на размер очереди, то есть, как задумано».Что приемлемо, если вы подаете несколько тысяч запросов ... очевидно, где-то должен быть предел.Это также может иметь смысл с точки зрения DoS (в противном случае вредоносная программа может заставить ядро ​​исчерпать память, отправив миллиард запросов).Но, тем не менее, это то, что вы можете реально встретить с «нормальными» числами (около сотни), и оно неожиданно вас поразит, что не годится.Плюс, если вы отправляете только полдюжины или около того запросов, и они немного больше (несколько мегабайт данных), то может произойти то же самое, по-видимому, потому что ядро ​​разбивает их в подзапросах.Что, опять-таки, имеет смысл, но, видя, что документы не говорят вам, следует ожидать, что не имеет значения (кроме того, что требуется больше времени), независимо от того, читаете ли вы 500 байтов или 50 мегабайт данных.

Кроме того, кажется, что нет никакого способа сделать буферизованный AIO, по крайней мере, на любой из моих систем Debian и Ubuntu (хотя я видел, как другие люди жалуются на прямо противоположное, то есть на самом деле небуферизованные записи проходят через буферы).Из того, что я вижу в своих системах, AIO действительно асинхронен только с отключенной буферизацией, и это позор (поэтому я вместо этого использую некрасивую конструкцию вокруг отображения памяти и рабочего потока).

Важной проблемой любого асинхронного является возможность epoll_wait () на нем, что важно, если вы делаете что-то еще, кроме дискового ввода-вывода (например, получение сетевого трафика).Конечно, есть io_getevents, но это не так желательно / полезно, так как он работает только для одной единственной вещи.

В последних версиях ядра есть поддержка eventfd .На первый взгляд, это кажется бесполезным, так как не очевидно, как это может быть полезно в любом случае.Тем не менее, для вашего спасения есть недокументированная функция io_set_eventfd , которая позволяет вам связать AIO с eventfd, который способен epoll_wait ().Чтобы узнать об этом, вам нужно пролистать заголовки, но он, безусловно, есть, и он прекрасно работает.

3 голосов
/ 12 октября 2010

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

Асинхронный дисковый ввод-вывод - это возможность неблокировать операции ввода-вывода диска (в одном потоке) и ожидать их завершения.Это прекрасно работает, http://lse.sourceforge.net/io/aio.html имеет больше информации.

AIO достаточно для того, чтобы типичное приложение (сервер базы данных) могло использовать его.AIO является хорошей альтернативой либо созданию большого количества потоков, выполняющих синхронный ввод-вывод, либо использованию scatter / collect в семействе системных вызовов preadv, которые сейчас существуют.

Можно выполнить работу синхронного ввода-вывода "список покупок", используяновый вызов preadv, куда пойдет ядро ​​и получит кучу страниц с разными смещениями в файле.Это нормально, если у вас есть только один файл для чтения.(NB: Эквивалентная функция записи существует.)

опрос, epoll и т. Д., Это просто причудливые способы выполнения select (), которые страдают от меньшего количества ограничений и проблем с масштабируемостью - их может не быть легко смешать с диском aio, но в реальном приложении вы, вероятно, можете обойти это довольно тривиально, используя потоки (некоторые серверы баз данных в любом случае, как правило, выполняют подобные операции в отдельных потоках).Poll () - это хорошо, epoll - лучше, для большого количества файловых дескрипторов.select () также подходит для небольшого числа файловых дескрипторов (или, в частности, для небольших файловых дескрипторов).

2 голосов
/ 12 октября 2010

Большая часть того, что я узнал об асинхронном вводе-выводе в Linux, была работа с источником Lighttpd . Это однопоточный веб-сервер, который обрабатывает много одновременных соединений, используя то, что, по его мнению, является лучшим из всех доступных асинхронных механизмов ввода / вывода в работающей системе. Посмотрите на источник, он поддерживает Linux, BSD и (я думаю) несколько других операционных систем.

...