Вход/Регистрация
Разработка приложений в среде Linux. Второе издание
вернуться

Троан Эрик В.

Шрифт:

67: perror("F_SETLEASE");

68: return 1;

69: }

70: }

71:

72: /* Пока файлы остаются открытыми, ожидать поступления сигналов. */

73: while (numFiles)

74: pause;

75:

76: return 0;

77: }

13.4. Альтернативы

read
и
write

Несмотря на то что системные вызовы

read
и
write
как нельзя лучше подходят приложениям для извлечения и хранения данных в файле, все же они не всегда являются самыми быстрыми методами. Они допускают управление отдельными порциями данных; для записи же нескольких порций данных требуется несколько системных вызовов. Подобным образом, если приложению необходим доступ к данным в разных частях файла, оно должно вызывать
lseek
между каждым
read
или
write
, удваивая количество необходимых системных вызовов. Для улучшения эффективности существуют другие системные вызовы.

13.4.1. Разбросанное/сборное чтение и запись

Приложениям часто требуется читать и записывать данные различных типов в последовательные области файла. Несмотря на то что это можно делать сравнительно легко с помощью множества вызовов

read
и
write
, такое решение не является особо эффективным. Вместо этого приложения могут перемещать все данные в последовательную область памяти, делая возможным один системный вызов. Однако эти действия приводят к множеству ненужных операций с памятью.

Linux предлагает системные вызовы

readv
и
writev
, реализующие разбросанное/сборное чтение и запись [98] . В отличие от стандартных элементов своего уровня, получающих по одному указателю и размеру буфера, эти системные вызовы получают массивы записей, каждая запись которых описывает буфер. Буферы читаются или записываются в том порядке, в каком они приведены в массиве. Каждый буфер описывается с помощью структуры
struct iovec
.

98

Они так именуются, поскольку чтение разбрасывает данные по всей памяти, а запись собирает данные из разных областей памяти. Они также известны как векторное чтение и запись. Этим объясняется наличие "v" в конце

readv
и
writev
.

#include <sys/uio.h>

struct iovec {

 void * iov_base; /* адрес буфера */

 size_t iov_len; /* длина буфера */

};

Первый элемент,

iov_base
, указывает на буферное пространство. Элемент
iov_len
— это количество символов в буфере. Эти элементы представляют собой то же, что и второй и третий параметры, передаваемые
read
и
write
.

Ниже показаны прототипы

readv
и
writev
.

#include <sys/uio.h>

int readv(int fd, const struct iovec * vector, size_t count);

int writev(int fd, const struct iovec * vector, size_t count);

Первый аргумент является файловым дескриптором, с которого можно считывать или на который можно записывать. Второй аргумент,

vector
, указывает на массив элементов
count struct iovec
. Обе функции возвращают общее количество прочитанных или записанных байтов.

Ниже приведена простая программа-пример, использующая

writev
для отображения простого сообщения на стандартном устройстве вывода.

 1: /* gather.с */

 2:

 3: #include <sys/uio.h>

 4:

 5: int main(void) {

 6: struct iovec buffers[3];

 7:

 8: buffers[0].iov_base = "hello";

 9: buffers[0].iov_len = 5;

10:

11: buffers[1].iov_base = " ";

12: buffers[1].iov_len = 1;

13:

14: buffers[2].iov_base = "world\n";

15: buffers[2].iov_len = 6;

16:

17: writev(1, buffers, 3);

18:

19: return 0;

20: }

13.4.2. Игнорирование указателя файла

  • Читать дальше
  • 1
  • ...
  • 99
  • 100
  • 101
  • 102
  • 103
  • 104
  • 105
  • 106
  • 107
  • 108
  • 109
  • ...

Ебукер (ebooker) – онлайн-библиотека на русском языке. Книги доступны онлайн, без утомительной регистрации. Огромный выбор и удобный дизайн, позволяющий читать без проблем. Добавляйте сайт в закладки! Все произведения загружаются пользователями: если считаете, что ваши авторские права нарушены – используйте форму обратной связи.

Полезные ссылки

  • Моя полка

Контакты

  • chitat.ebooker@gmail.com

Подпишитесь на рассылку: