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.12 Копирование файла с помощью асинхронного ввода-вывода

Распечатка 7.12 Копирование файла с помощью асинхронного ввода-вывода

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

Распечатка 7.12.

 

/* aio_cp.c */

 

#include <unistd.h>

#include <aio.h>

#include <sys/types.h>

#include <errno.h>

 

#define INPUT_FILE "./input"

#define OUTPUT_FILE "./output"

/* Размер для передачи в одной операции чтения или записи */

#define XFER_SIZE 1024

#define MAX 3

 

/* Функция для заполнения aiocb значениями */

void populate_aiocb(struct aiocb *aio, int fd, off_t offset,

                    int bytes, char *buf){

  aio->aio_fildes = fd;

  aio->aio_offset = offset;

 

  /*

   * Мы не используем здесь механизм уведомления, чтобы уделить

   * больше внимания интерфейсам AIO. Для получения уведомления

   * после завершения AIO мы можем использовать механизмы

   * уведомления либо SIGEV_SIGNAL, либо SIGEV_THREAD

   */

  aio->aio_sigevent.sigev_notify = SIGEV_NONE;

  aio->aio_nbytes = bytes;

  aio->aio_buf = buf;

}

 

/*

 * Это приложение копирует один файл в другой

 */

int main(){

 

  /* Файловые дескрипторы чтения/записи */

  int fd_r , fd_w;

  /* Блоки управления AIO для чтения и записи */

  struct aiocb a_write, a_read;

 

  /*

   * Этот список используется для хранения блоков

   * управления исходящих запросов чтения или записи

   */

  struct aiocb *cblist[MAX];

  /* Статус операции чтения или записи */

  int err_r, err_w;

  /* число на самом деле считанных байтов */

  int read_n = 0;

  /* Метка завершения потока для файла-источника */

  int quit = 0;

  /* Используются для передачи данных между источником

   * и файлом назначения

   */

  char read_buf[XFER_SIZE];

  char write_buf[XFER_SIZE];

 

  /*

   * Открываем файлы источника и места назначения. Вызываем

   * функцию populate_aiocb, чтобы проинициализировать блоки

   * управления AIO для операции чтения и записи. Хорошей

   * практикой является очистка блоков aiocb перед

   * их использованием

   */

  fd_r = open(INPUT_FILE, O_RDONLY, 0444);

  fd_w = open(OUTPUT_FILE, O_CREAT | O_WRONLY, 0644);

 

  memset(&a_write, 0 , sizeof(struct aiocb));

  memset(&a_read, 0 , sizeof(struct aiocb));

 

  /* Заполняем блоки aiocb значениями по умолчанию */

  populate_aiocb(&a_read, fd_r, 0, XFER_SIZE, read_buf);

  populate_aiocb(&a_write, fd_w, 0, XFER_SIZE, write_buf);

 

  /*

   * Запускаем асинхронное чтение из файла-источника с помощью

   * функции aio_read. Эта функция читает a_read.aio_nbytes

   * байтов из файла a_read.aio_fildes, начиная со смещения

   * a_read.aio_offset в буфер a_read.aio_buf. В случае успеха

   * возвращается 0. Эта функция возвращается сразу после

   * помещения запроса в очередь.

   */

  aio_read(&a_read);

 

  /*

   * Ожидаем завершения чтения. После старта любой асинхронной

   * операции (чтения или записи), можно получить её статус с

   * помощью функции aio_error. Если запрос не завершён, эта

   * функция возвращает EINPROGRESS, если запрос завершён

   * успешно, она возвращает 0, в противном случае возвращается

   * значение ошибки. Если aio_read возвращает EINPROGRESS, вызов

   * aio_suspend ожидает завершения операции.

   */

  while((err_r = aio_error(&a_read)) == EINPROGRESS){

    /*

     * Функция aio_suspend приостанавливает вызывающий процесс,

     * пока не завершится по крайней мере один из асинхронных

     * запросов ввода/вывода в списке cblist, или не будет

     * доставлен сигнал. Здесь мы ждём завершения aio_read

     * для блока a_read.

     */

    cblist[0] = &a_read;

    aio_suspend(cblist, 1, NULL);

  }

 

  /*

   * Если возвращаемое значение функции aio_error равно 0, то

   * операция чтения была успешной. Вызываем aio_return, чтобы

   * узнать количество прочитанных байтов. Функция должна быть

   * вызвана только один раз после того, как aio_error

   * возвращает нечто, отличное от EINPROGRESS.

   */

  if (err_r == 0){

    read_n = aio_return(&a_read);

    if (read_n == XFER_SIZE)

      /* Смещениями должны управлять мы */

      a_read.aio_offset += XFER_SIZE;

    else {

      /*

       * Для простоты предположим, что размер файла-источника

       * больше, чем XFER_SIZE

       */

      printf(“Source file size < %d\n”, XFER_SIZE);

      exit(1);

    }

  }

 

  /*

   * В этом цикле мы копируем данные, считанные выше, в буфер

   * записи и запускаем операцию асинхронной записи. Также,

   * думаем вперёд и помещаем в очередь запрос на чтение для

   * следующего цикла.

   */

  while(1){

    memcpy(write_buf, read_buf, read_n);

 

    /*

     * Настраиваем блок управления записи. Чтобы поместить в

     * очередь запрос на запись вызываем aio_write. Эта функция

     * запишет a_write.aio_nbytes байтов из буфера

     * a_write.aio_buf в файл a_write.aio_fildes со смещением

     * a_write.aio_offset. В случае успеха возвращает 0.

     */

    a_write.aio_nbytes = read_n;

    aio_write(&a_write);

 

    /* Помещаем в очередь следующий запрос на чтение */

    a_read.aio_nbytes = XFER_SIZE;

    aio_read(&a_read);

 

    /*

     * Перед началом обработки ожидаем завершения и чтения,

     * и записи

     */

    while((err_r = aio_error(&a_read)) == EINPROGRESS ||

          (err_w = aio_error(&a_write)) == EINPROGRESS){

      cblist[0] = &a_read;

      cblist[1] = &a_write;

      aio_suspend(cblist, 2, NULL);

    }

 

    /* Это конец? */

    if (quit)

      break;

    /* Увеличиваем на единицу указатель записи */

    a_write.aio_offset += aio_return(&a_write);

    /* Увеличиваем на единицу указатель чтения */

    read_n = aio_return(&a_read);

    if (read_n == XFER_SIZE)

      a_read.aio_offset += XFER_SIZE;

    else

      /* Это последний блок */

      quit = 1;

    }

  }

 

  /* Очистка */

  close(fd_r);

  close(fd_w);

}

 

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