vak: (Default)
Serge Vakulenko ([personal profile] vak) wrote2025-02-18 06:23 pm

Асинхронный линукс

Народ, кто-нибудь уже поимел опыт с <linux/io_uring.h>? Как оно по жизни?

Неожиданно для себя обнаружил, что в Линуксе пять лет назад появилась крутая фича. А именно три системных вызова, реализующих эффективный асинхронный интерфейс ко всем сервисам ядра.
  • int io_uring_setup(unsigned entries, struct io_uring_params *p);
  • int io_uring_enter(unsigned fd, unsigned to_submit, unsigned min_complete, unsigned flags, sigset_t *sig);
  • int io_uring_register(unsigned fd, unsigned opcode, void *arg, unsigned nr_args);
Революционная штука, как я погляжу. Может коренным образом изменить подход к разработке приложений. Только сложновато для программиста выходит. Есть статьи про это дело.

[personal profile] ichthuss 2025-02-19 10:41 am (UTC)(link)
Не обязательно ждать. Несколько собітий могут и так накопиться за то время, пока мі обрабатівали предідущий возврат из системного візова. В єтом случае мі получаем несколько собітий за один системній візов и с нулевой латентностью.

[personal profile] chabapok 2025-02-19 03:26 pm (UTC)(link)
> Несколько собітий могут и так накопиться за то время, пока мі обрабатівали предідущий возврат из системного візова

там эта очередь - многопоточная, что ли? Один поток уже обрабатывает возврат, а другой поток все еще может в эту очередь что-то добавить. А потом хоба - и уже в какой-то момент считатется, что возврат произошел, и события больше не добавляются в эту очередь. Например таким моментом может быть обращение к size(). Ну то есть, начало работы с элементами.

Ну, вприницпе, да. Полезно.
Edited 2025-02-19 15:35 (UTC)

[personal profile] ichthuss 2025-02-20 08:36 am (UTC)(link)
Не уверен, что понял ваш комментарий. Суть именно в том, чтобі в одном треде обрабатівать много одновременніх операций (которіе традиционно бі обрабатівались в разніх тредах). Т.е., условно говоря, возможен подобная последовательность собітий:
- мі имеем сокеті к 100к клиентов. сабмитим 100к запросов на чтение одним сисколлом, ждем ответа
- получаем ответ, обрабатіваем запрос клиента, формируем ответ, сабмитим респонз
- за время, пока мі обрабатівали, пришло еще 10 запросов от клиента, они сразу нам доступні для обработки, уже лежать в кольцевом буфере - пока мі обрабатівали запрос в юзерспейсе, ядро тоже времени не теряло
- мі последовательно обрабатіваем єти запросі, за єто время заканчивается обработка отправки нашего респонза первому клиенту, и єто собітие тоже попадает в буфер
- когда очередь доходит до обработки собітия завершения передачи респонза, мі в ответ опять сабмитим запрос на чтение из єтого сокета.

Ну и т.д. Я не уверен, что ві именно єто имели ввиду под "многопоточной очередью".

[personal profile] chabapok 2025-02-20 11:39 am (UTC)(link)
нет, я не єто имел в виду.

для начала мне уже ясно: надо либо читать документацию - либо мы говорим, что пофантазируем как оно могло бы работать правильно. Сейчас мы занимаемся вторым. Надо это понимать.

> за время, пока мі обрабатівали, пришло еще 10 запросов от клиента, они сразу нам доступні для обработки,

а вот єто без многопотока невозможно. То есть тут есть всего 2 варианта: либо мы делаем некий вызов, возвращающий новые события. И тогда єто 1 поток. Либо же мы таких вызовов не делаем, а наша входящая очередь многопоточная, и читатель в ней один (мы), а все писатели в ядре и их много (сокеты, клики мышкой и тд).

> Суть именно в том, чтобі в одном треде обрабатівать много одновременніх операций

а чем это принципиально от epoll отличается? В epoll ты сделал вызов - а тебе возвращается список сокетов, по которым есть обновление (данные для чтения, или появившаяся возможность записать еще если это tcp).

Кстати. Когда сетевая карточка генерирует прерывание, то по умолчанию оно приходит на любое ядро. (можно настроить, запретив какое-то ядро - но нужно ли?) Соответственно, получается задача, что данные из нескольких потоков надо свести в один. Зачем так сделано, я не очень понимаю. Как показала практика, не всегда с первого раза архитектуры делают удачно. С другой же стороны, те кто это делал, явно знали больше, чем я. Тут я затрудняюсь дать оценку. Наверное в каких-то случаях это хорошо, а в каких-то других нет.