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