буферизованный асинхронный файловый ввод / вывод в Linux - PullRequest
31 голосов
/ 14 апреля 2011

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

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

Нативный API ядра aio работает только с небуферизованными операциями, исправления для ядра для добавления поддержки буферизованных операций существуют, но им более 3 лет, и, похоже, никто не заботится об их интеграции в основную линию.1005 *

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

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

Ответы [ 3 ]

35 голосов
/ 14 апреля 2011

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

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

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

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

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

3 голосов
/ 14 апреля 2011

Материал кажется старым - ну, он - старый - потому что он существует давно и, хотя ни в коем случае не тривиально, хорошо понят. Решение, которое вы можете поднять, опубликовано в превосходной и беспримерной книге У. Ричарда Стивенса (читайте «Библию»). Книга - это редкое сокровище, ясное, краткое и полное: каждая страница дает реальную и непосредственную ценность:

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

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

Том 1: API сетевого интерфейса сокетов (с Феннером и Рудоффом) и
Том 2: Межпроцессное взаимодействие

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

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

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

2 голосов
/ 08 февраля 2013

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

Более подробная информация о текущем состоянии мира здесь: https://github.com/littledan/linux-aio. Он был обновлен в 2012 году кем-то, кто раньше работал в Google.

...