@Z3liboba
Студент, учусь программировать

Как в io_uring отправить sqe, чтобы sqe выполнилось через 3 секунды после io_uring_submit?

Пишу ассинхронный tcp сервер приема сообщений с использованием liburing. Логика работы сервера:
Открываем текстовый файл FILE.txt, в sq отправляем accept, после чего сабмитим, после в sq отправляем запись сообщенияв FILE.txt из клиентского сокета, ждем 3 секунды и отправляем клиенту accept.

Сделал все кроме задержки, код работает ассинхронно, но как выполнить задержку не понимаю, sleep() тормозит весь код, предполагаю, что нужно настроить параметры sqe, чтобы после сабмита код выполнился через 3 секунды, но как это сделать не представляю

Извините, если я коряво задал вопрос, программирование только изучаю, второй курс универа, заранее спасибо за вашу помощь!
  • Вопрос задан
  • 71 просмотр
Пригласить эксперта
Ответы на вопрос 1
jcmvbkbc
@jcmvbkbc
"I'm here to consult you" © Dogbert
как выполнить задержку не понимаю

Для организации таймаута в liburing есть io_uring_prep_timeout, но кроме этого нужно сериализовать таймаут и все предыдущие команды (чтобы таймаут начинался после их окончания) и следующую после таймаута команду и сам таймаут (чтобы последующие команды не стартовали вместе с таймаутом). Сериализация делается установкой флага IOSQE_IO_DRAIN для sqe, почитать об этом можно например здесь. У меня нарисовался следующий пример, который записывает в файл (stderr), делает паузу в одну секунду, а потом записывает ещё:
#include <fcntl.h>
#include <liburing.h>
#include <stdio.h>
#include <sys/mman.h>

#define QUEUE_DEPTH 16

int main(int argc, char **argv)
{
        int i;
        struct io_uring ring;
        struct io_uring_cqe *pcqe;
        static const char msg0[] = "before timeout\n";
        static const char msg1[] = "after timeout\n";
        struct io_uring_sqe *sqe;

        io_uring_queue_init(QUEUE_DEPTH, &ring, 0);
        io_uring_prep_write(io_uring_get_sqe(&ring), 2, msg0, sizeof(msg0), 0);

        sqe = io_uring_get_sqe(&ring);
        io_uring_prep_timeout(sqe, (struct __kernel_timespec[]){{.tv_sec = 1}},
                              -1, IORING_TIMEOUT_ETIME_SUCCESS);
        io_uring_sqe_set_flags(sqe, IOSQE_IO_DRAIN);

        sqe = io_uring_get_sqe(&ring);
        io_uring_prep_write(sqe, 2, msg1, sizeof(msg1), 0);
        io_uring_sqe_set_flags(sqe, IOSQE_IO_DRAIN);
        io_uring_submit(&ring);
        for (i = 0; i < 3; ++i) {
                int rv = io_uring_wait_cqe(&ring, &pcqe);
                if (rv < 0) {
                        errno = -rv;
                        perror("io_uring_wait_cqe");
                } else {
                        io_uring_cqe_seen(&ring, pcqe);
                }
        }
}
Ответ написан
Комментировать
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Войти через центр авторизации
Похожие вопросы