Я устанавливаю асинхронизированный модуль записи и хочу, чтобы порядок операций с файлом был гарантирован этим.Я использую это как писатель в другой программе, которая читает файл 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: Файл имеет .......-байтовый пакет, больше чем максимум 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 гарантирует и поддерживает порядок работы?если ответ «нет», то в чем моя проблема с кодом и логикой?
Любая помощь будет оценена.