aio_write() и lio_listio() POSIX AIO не работают правильно в операции записи

Я настраиваю асинхронизированный модуль записи и хочу, чтобы порядок операций над файлом был гарантирован этим. Я использую это как писатель в другой программе, которая читает файл pcap. Учтите, что я уже пытался отдельно использовать linux-aio и POSIX aio в своем коде для записи файла pcap на диск. Мне нужно знать, гарантируется ли выполнение aio_write() и lio_listio() POSIX AIO по порядку?

В linux-aio я использую структуру iocb для представления одного запроса на операцию записи. После фиксированного номера одной операции блоки io_getevents до отчета о завершении фиксированного номера.

struct iocb io_cb;
memset(&io_cb, 0, sizeof(io_cb));
io_cb.aio_fildes = file_descriptor;
io_cb.aio_lio_opcode = IOCB_CMD_PWRITE;
io_cb.aio_reqprio = 0;
io_cb.aio_buf = (__u64)(buffer);
io_cb.aio_nbytes = size;
io_cb.aio_offset = 0;
struct iocb* io_cb_pointer = &io_cb;
static int32_t BLOCKS_COUNT = 1;
syscall(SYS_io_submit, io_context, BLOCKS_COUNT, &io_cb_pointer) 
write_count++;
 if ((write_count == MAX_EVENT_COUNT) || flush == true)//flush is to flush before exit program.
    {
        struct io_event* events = (struct io_event *)malloc((write_count) * sizeof(struct io_event));
        syscall(SYS_io_getevents, io_context, write_count / 2, MAX_EVENT_COUNT, events, NULL)
    }

приведенный выше фрагмент кода, который пишет ответственно, приводит к правильному выводу pcap, который может быть открыт Wireshark.

Но моя проблема с POSIX aio, который, похоже, не гарантирует порядок выполнения операций. Часть кода написана ниже:

    aiocb_array = calloc(MAX_EVENT_COUNT, sizeof (struct aiocb*));
    aiocb_element = calloc(MAX_EVENT_COUNT, sizeof (struct aiocb));
...
    struct aiocb** aiocb_array;
    struct aiocb* aiocb_element;
...
    static size_t pre_nbytes = 0;
    static __off_t pre_offset = 24;//Due to pcap header file length
    aiocb_element[write_count].aio_fildes = file_descriptor;
    aiocb_element[write_count].aio_lio_opcode = LIO_WRITE;
    aiocb_element[write_count].aio_reqprio = 0;
    aiocb_element[write_count].aio_buf = (void *)(buffer);
    aiocb_element[write_count].aio_nbytes = size;
    aiocb_element[write_count].aio_offset = pre_nbytes + pre_offset;

    pre_nbytes = size;
    pre_offset = aiocb_element[write_count].aio_offset;

    aiocb_array[write_count] = &aiocb_element[write_count];
    write_count++;
        if ((write_count == MAX_EVENT_COUNT) || flush == true )//flush is to flush before exit program.
    {
        if(flush)
        {
            if(lio_listio(LIO_WAIT, aiocb_array, write_count, NULL) != 0)
            {
                 printf("Flush lio_listio errno :%d\n", errno);
                 input->error_code = errno;
                 return false;
            }
        }
        else
        {
            if(lio_listio(LIO_NOWAIT, aiocb_array, write_count, NULL) != 0)
            {
                 printf("lio_listio errno :%d\n", errno);
                 input->error_code = errno;
                 return false;
            }
        }

        if(write_count == MAX_EVENT_COUNT)
            write_count = 0;
    }

Как ясно из приведенного выше кода, я подготавливаю запрос на запись в структуре aiocb и присваиваю ему смещение, поскольку файл, который используется для записи, был открыт без режима добавления. фрагмент кода генерирует файл pcap, который имеет тот же байт, что и входной pcap, но, к сожалению, Wireshark не может открыть его и выдает ошибку, которая указывает: "Файл захвата, похоже, поврежден или поврежден. (pcap: Файл имеет....... -byte пакет больше, чем максимум 0f 65535) ". Но когда я вызываю lio_listio в режиме LIO_WAIT и устанавливаю MAX_EVENT_COUNT = 1, он генерирует правильный вывод pcap, который может быть правильно открыт Wireshark.

Кроме того, когда я заменяю lio_listio на функцию aio_write в POSIX, он снова создает поврежденный файл. В соответствии с упомянутым условием, которое приводит к правильному выводу pcap, кажется, что lio_listio и функция aio_write порядка выполнения POSIX отличаются от порядка отправки программы !!! Проводил ли он операции в произвольном порядке? если ответ "да", то почему игнорируется значение смещения, и правильный вывод не генерируется? почему linux-aio гарантирует и поддерживает порядок работы? если ответ "нет", то в чем проблема моего кода и логики?

Любая помощь будет оценена.

+1
источник поделиться

На данный вопрос пока никто не ответил

Посмотрите похожие вопросы:

Посмотрите другие вопросы по меткам или Задайте вопрос