Выпуск библиотеки libuv 1.45.0 с поддержкой подсистемы io_uring

Опубликован выпуск библиотеки libuv 1.45.0, применяемой для мультиплексирования соединений и асинхронной обработки ввода/вывода во многих проектах, нацеленных на высокопроизводительную обработку сетевых и файловых запросов, например, в платформе Node.js, DNS-серверах BIND 9 и Knot DNS, HTTP-сервере H2O, Lua-фреймворке Luvit, виртуальной машине MoarVM, языке Julia и Python-фреймворке uvloop. Библиотека позволяет организовать цикл обработки событий в неблокирующем режиме, реализованный на базе таких методов, как epoll в Linux, kqueue в BSD и macOS, IOCP в Windows и event ports в Solaris. Код проекта написан на языке Си и распространяется под лицензией MIT.

Для приложений доступны многоплатформенные функции для работы с сетевыми соединениями TCP и UDP в асинхронном режиме, асинхронного разрешения имён DNS, асинхронной работой с файлами, отслеживании событий в файловой системе, организации IPC для совместного доступа к сокетам, организации пула потоков (Thread pool), обработки сигналов и использования высокоточных таймеров. Также библиотека включает примитивы для организации многопоточного выполнения и синхронизации потоков. В сочетании с циклом обработки событий применяются два базовых абстрактных высокоуровневых примитива: “дескрипторы” (handles) для реализации долгоживущих объектов, выполняющих несколько операций, и “запросы” (requests) для выполнения короткоживущих запросов.


Ключевым улучшением в новом выпуске стала реализация давно ожидаемой поддержки интерфейса асинхронного ввода/вывода io_uring, предоставляемого ядром Linux, начиная с выпуска 5.1, и примечательного поддержкой полинга (polling) ввода/вывода и возможностью работы как с буферизацией, так и без буферизации. В API io_uring разработчики ядра попытались устранить недостатки старого интерфейса aio. По производительности io_uring очень близок к SPDK и существенно опережает libaio при работе с включённым полингом.

В libuv интерфейс io_uring может применяться на платформах Linux с ядром 5.1+ в примитивах для асинхронной работы с файлами, таких как read, write, fsync, fdatasync, stat, fstat и lstat. На других ОС и системах со старым ядром продолжает использоваться пул потоков. Проведённые тесты производительности показали, что применение io_uring
в libuv позволяет добиться повышения пропускной способности в 8 раз. Работа по добавлению io_uring в libuv проведена при поддержке организации ISC (Internet Systems Consortium), применяющей рассматриваемую библиотеку в DNS-сервере BIND.

Из других улучшений в новой версии выделяется выставление единого размера стека в 8 МБ для пула потоков на всех архитектурах и платформах. Добавлен новый API uv_metrics_info() для сбора метрик, таких как счётчик итераций в цикле событий, общее число обработанных событий и число событий, ожидающих в очереди во время отправки запроса.

Release. Ссылка here.