Подтвердить что ты не робот

Буферизованный асинхронный ввод/вывод файлов в Linux

Я ищу наиболее эффективный способ выполнения асинхронных операций ввода-вывода файлов в Linux.

В реализации POSIX glibc используются потоки в пользовательской области.

Собственное aio kernel api работает только с небуферизованными операциями, существуют патчи для ядра, чтобы добавить поддержку буферизированных операций, но это > 3 года, и никто, кажется, не заботится об их интеграции в магистраль.

Я нашел много других идей, понятий, патчей, которые позволяли бы асинхронный ввод-вывод, хотя большинство из них в статьях, которым также было 3 года. Что из этого действительно доступно в сегодняшнем ядре? Я читал о сервлетах, играх, материалах с потоками ядра и многом другом, о которых я даже не помню.

Каков наиболее эффективный способ ввода/вывода буферизованных асинхронных файлов в текущем ядре?

4b9b3361

Ответ 1

Если вы не хотите писать свой собственный пул потоков ввода-вывода, реализация glibc является приемлемым решением. Он действительно работает на удивление хорошо для чего-то, что полностью работает в пользовательском пространстве.

Реализация ядра не работает с буферизованным IO вообще в моем опыте (хотя я видел, как другие люди говорят об обратном!). Это нормально, если вы хотите читать огромные объемы данных через DMA, но, конечно, это отстойное время, если вы планируете использовать буферный кеш. Также обратите внимание, что вызовы ядра AIO могут фактически блокироваться. Существует командный буфер ограниченного размера, и большие чтения разбиваются на несколько более мелких. Когда очередь заполнена, асинхронные команды выполняются синхронно. Сюрприз. Я столкнулся с этой проблемой год или два назад и не смог найти объяснения. Отвечая на вопрос, я ответил: "Да, конечно, как это работает". Из того, что я понял, "официальный" интерес к поддержке буферизованного айо также не очень хорош, несмотря на то, что несколько рабочих решений, похоже, доступны в течение многих лет. Некоторые из аргументов, которые я читал, были в строках "вы не хотите использовать буферы в любом случае" и "никто этого не требует", и "большинство людей даже не используют epoll". Итак, хорошо... meh.

Возможность получить epoll, сигнализируемую завершенной операцией async, была другой проблемой до недавнего времени, но в то же время это отлично работает с помощью eventfd.

Обратите внимание, что реализация glibc фактически порождает потоки по требованию внутри __aio_enqueue_request. Это, вероятно, не имеет большого значения, поскольку нерестовые потоки уже не так дороги, но об этом нужно знать. Если ваше понимание запуска асинхронной операции "немедленно возвращается", то это предположение может быть неверным, поскольку оно может сначала порождать некоторые потоки.

ИЗМЕНИТЬ:
В качестве побочного элемента под Windows существует очень похожая ситуация с тем, что реализовано в реализации glibc AIO, где предположение о "немедленном возврате" в очереди на асинхронную операцию неверно.
Если все данные, которые вы хотите прочитать, находятся в кеше буфера, Windows решит, что вместо этого он будет запускать запрос синхронно, потому что он все равно будет завершен. Это хорошо документировано и, по общему признанию, тоже звучит замечательно. За исключением случаев, когда есть несколько мегабайт для копирования или в случае, если другой поток имеет ошибки страницы или делает IO одновременно (таким образом, конкурируя за блокировку) "сразу" может быть неожиданно долгое время - я видел "немедленные" времена 2 -5 миллисекунд. Это не проблема в большинстве ситуаций, но, например, при ограничении времени кадра 16,66 мс, вы, вероятно, не хотите рисковать блокировкой в ​​течение 5 мс в случайные моменты времени. Таким образом, наивное предположение о том, что "может сделать async IO из моего потока рендеринга без проблем, поскольку async не блокирует", является ошибочным.

Ответ 2

Материал кажется старым - ну, он старый - потому что он был длинным и, хотя отнюдь не тривиальным, хорошо разбирается. Решение, которое вы можете снять, опубликовано в W. Richard Stevens превосходной и беспрецедентной книге (читайте "Библию" ). Книга представляет собой редкое сокровище, которое является ясным, кратким и полным: каждая страница дает реальную и непосредственную ценность:

    Расширенное программирование в среде UNIX

Два других таких, также Стивенс, являются первыми двумя томами его коллекции Unix Network Programming:

    Том 1: Сетевой интерфейс Sockets (с Fenner and Rudoff ) и
    Том 2: Interprocess Communications

Я не могу представить себя без этих трех фундаментальных книг; Я ошарашен, когда нахожу того, кто не слышал о них.

Еще больше книг Стивена, столь же драгоценных:

    TCP/IP Illustrated, Vol. 1: Протоколы

Ответ 3

Я не думаю, что реализация ядра ядра асинхронного ввода-вывода Linux действительно может использоваться, если вы также не используете O_DIRECT, извините.

Здесь больше информации о текущем состоянии мира: http://code.google.com/p/kernel/wiki/AIOUserGuide. Он был обновлен в 2012 году Googler.