The website "dmilvdv.narod.ru." is not registered with uCoz.
If you are absolutely sure your website must be here,
please contact our Support Team.
If you were searching for something on the Internet and ended up here, try again:

About uCoz web-service

Community

Legal information

7.3.8 Асинхронный ввод-вывод

7.3.8 Асинхронный ввод-вывод

Предыдущая  Содержание  Следующая V*D*V

Традиционные системные вызовы чтения и записи являются блокирующими вызовами. Большинство приложений реального времени может нуждаться в прерывании их работы и процесса ввода/вывода с целью улучшения детерминизма. Например, приложение может предпочесть асинхронный ввод/вывод (Asynchronous I/O, AIO), если требуется сбор большого объёма данных от какого-то источника и если обработка данных - интенсивное вычисление. POSIX.1b определяет асинхронные интерфейсы ввода/вывода для выполнения требований таких приложений.

Механизм очень прост. Приложение может поместить в очередь запрос на AIO, а затем продолжить нормальную обработку. По завершении ввода/вывода приложение уведомляется. Затем оно может запросить состояние ввода/вывода, чтобы узнать был ли он успешным или закончился неудачей. Используя интерфейсы AIO, приложение может выполнять следующие операции:

 

Формировать нескольких неблокирующих запросов ввода/вывода для различных источников с помощью единственного вызова. (Таким образом, приложение может иметь много операций ввода/вывода в процессе выполнения, в то время как оно выполняет другой код.)

Отменять любые не выполненные запросы ввода/вывода.

Ожидать завершения ввода/вывода.

Отслеживать состояние ввода/вывода: в процессе работы, ошибка, или завершён.

 

Блок управления асинхронным вводом-выводом

 

Блок управления AIO, структура aiocb, является ядром AIO POSIX.1b. Эта структура содержит сведения, которые необходимы для представления AIO. Структура определяется следующим образом:

 

struct aiocb

{

  int aio_fildes;              /* Файловый дескриптор. */

  int aio_lio_opcode;          /* Операция для выполнения,

                                  чтение или запись. Используется

                                  при нескольких запросах AIO

                                  в одном запросе */

  int aio_reqprio;              /* Изменение приоритета запроса. */

  volatile void *aio_buf;       /* Расположение буфера для чтения

                                   или записи */

  size_t aio_nbytes;            /* Размер передачи. */

  struct sigevent aio_sigevent; /* Информация уведомления. */

  off_t aio_offset;             /* Смещение в файле для начала

                                   чтения или записи в него */

}

 

Обратите внимание, что в отличие от традиционных операций чтения или записи, вам необходимо указать смещение в файле, откуда должен начаться AIO. После выполнения ввода/вывода ядро не будет увеличивать значение поля, содержащее смещение в файле, в файловом дескрипторе. Вы должны следить за смещениями в файле вручную.

 

Функции асинхронного ввода-вывода

 

Функции AIO приведены в Таблице 7.11. Использование интерфейсов AIO POSIX.1b иллюстрирует Распечатка 7.12. Этот пример просто копирует один файл в другой с помощью AIO. Для простоты будем считать, что функции AIO не возвращают ошибку.

 

Таблица 7.11 Функции асинхронного ввода-вывода

 

Метод

Описание

aio_read

Старт асинхронного чтения.

aio_write

Старт асинхронной записи.

aio_error

Возвращает статус завершения последней aio_read или aio_write.

aio_return

Возвращает число байт, переданных в aio_read или aio_write.

aio_cancel

Отменяет любые ожидающие операции AIO.

aio_suspend

Вызывает процесс, если завершается любой из указанных запросов.

lio_listio

Запрос нескольких операций чтения или записи.

 

Ввод/вывод, направляемый в список

 

Для передачи произвольного числа запросов чтения или записи в одном вызове может быть использована функция lio_listio:

 

int lio_listio(int mode, struct aiocb *list[], int nent,

               struct sigevent *sig);

 

mode: этот аргумент может быть LIO_WAIT или LIO_NOWAIT. Если этот аргумент имеет значение LIO_WAIT, функция ждёт, пока все вводы-выводы завершатся и sig игнорируется. Если аргументом является LIO_NOWAIT, функция возвращается немедленно и после завершения ввода/вывода будет происходить асинхронное уведомление, как указано в sig.

Список aiocb: этот аргумент содержит список aiocb.

nent: количество aiocb во втором аргументе.

sig: желаемый механизм уведомления. Уведомление не генерируется, если этот аргумент NULL.

 

Распечатка 7.12 может быть изменена для использования функции lio_listio.

 

while(1){

  memcpy(write_buf, read_buf, read_n);

  a_write.aio_nbytes = read_n;

  a_read.aio_nbytes = XFER_SIZE;

 

  /* Готовим список aiocb для lio_listio */

  cblist_lio[0] = &a_read;

  cblist_lio[1] = &a_write;

 

  /*

   * Вызываем lio_listio, чтобы отправить запросы

   * асинхронного чтения и записи

   */

  lio_listio(LIO_NOWAIT, cblist_lio, 2, NULL);

        ……………

}

 

Реализация в Linux

 

Первоначально AIO в Linux был полностью реализован в пользовательском пространстве с помощью потоков. Был один пользовательский поток, создаваемый для каждого запроса. Это привело к плохой масштабируемости и низкой производительности. Начиная с версии 2.5, в ядро была добавлена поддержка AIO. Тем не менее, интерфейсы ядра, предоставляющие AIO, отличаются от интерфейсов POSIX. Интерфейсы базируются на новом наборе системных вызовов. Они перечислены в Таблице 7.12. Эти интерфейсы предоставляются в пользовательском пространстве библиотекой libaio.

 

Таблица 7.12 Интерфейсы асинхронного ввода-вывода в ядре

 

Метод

Описание

io_setup

Создание нового контекста запросов для AIO.

io_submit

Отправка запроса AIO

(также известна как aio_read, aio_write, lio_listio).

io_getevents

Узнать о завершённых операциях ввода/вывода

(также известна как aio_error, aio_return).

io_wait

Ожидание завершения ввода/вывода (также известна как aio_suspend).

io_cancel

Отмена I/O (также известна как aio_cancel).

io_destroy

Уничтожение контекста AIO. Происходит по умолчанию при завершении процесса.

 

Что следует помнить

 

Блок управления не должен изменяться во время выполнения операции чтения или записи. Также, указатель буфера в aiocb должен быть действителен, пока запрос не завершен.

Возвращаемое значение lio_listio не указывает состояние отдельных запросов ввода/вывода. Неудачное завершение запроса не препятствует завершению других запросов.

 

Предыдущая  Содержание  Следующая