Читаем Linux API. Исчерпывающее руководство полностью

Согласно стандарту SUSv3, аргумент offset вызова mmap() должен выравниваться по странице; то же самое касается аргумента addr, если указан флаг MAP_FIXED. Linux соответствует этой спецификации. Но впоследствии было отмечено, что данные требования расходятся с более ранними стандартами, которые не так жестко регулировали поведение указанных аргументов. В результате такой формулировки ряд стандартных реализаций формально (и без особой на то причины) перестали считаться таковыми. Стандарт SUSv4 возвращается к менее строгим требованиям:

• реализация может требовать, чтобы аргумент offset был кратным размеру страницы в системе;

• при указании флага MAP_FIXED реализация может требовать выравнивания аргумента addr по странице;

• если указан флаг MAP_FIXED, а addr не равен нулю, то аргументы addr и offset будут иметь остаток после деления, равный размеру страницы в системе.

Похожая ситуация сложилась с аргументом addr в вызовах mprotect(), msync() и munmap(). Стандарт SUSv3 гласит, что он должен быть выровнен по странице, однако в стандарте SUSv4 это требование смягчено и оставлено на усмотрение реализации.

Пример программы

В листинге 45.1 демонстрируется применение вызова mmap() для создания приватного файлового отображения. Данная программа является упрощенной версией команды cat(1). Она отображает файл (целиком), имя которого задано в виде аргумента командной строки, и затем записывает содержимое отображения в стандартный вывод.

Листинг 45.1. Использование mmap() для создания приватного файлового отображения

mmap/mmcat.c

#include

#include

#include

#include "tlpi_hdr.h"

int

main(int argc, char *argv[])

{

char *addr;

int fd;

struct stat sb;

if (argc!= 2 || strcmp(argv[1], "-help") == 0)

usageErr("%s file\n", argv[0]);

fd = open(argv[1], O_RDONLY);

if (fd == -1)

errExit("open");

/* Получаем размер файла и указываем на его основе размеры отображения

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

if (fstat(fd, &sb) == -1)

errExit("fstat");

addr = mmap(NULL, sb.st_size, PROT_READ, MAP_PRIVATE, fd, 0);

if (addr == MAP_FAILED)

errExit("mmap");

if (write(STDOUT_FILENO, addr, sb.st_size)!= sb.st_size)

fatal("partial/failed write");

exit(EXIT_SUCCESS);

}

mmap/mmcat.c

45.3. Удаление отображения с участка памяти: munmap()

Системный вызов munmap() выполняет действие, обратное mmap(), — удаляет отображение из виртуального адресного пространства вызывающего процесса.

#include

int munmap(void *addr, size_t length);

Возвращает 0 при успешном завершении или –1 при ошибке

Аргумент addr обозначает начальный адрес участка памяти, с которого нужно удалить отображение. Он должен совпадать с началом страницы (в стандарте SUSv3 это обязательное требование, но стандарт SUSv4 всего лишь предусматривает такую возможность).

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

Обычно отображение удаляется целиком. Следовательно, нужно указать адрес, возвращенный предыдущим вызовом mmap(), и использовать то же значение length, что и при создании отображения. Например:

addr = mmap(NULL, length, PROT_READ | PROT_WRITE, MAP_PRIVATE, fd, 0);

if (addr == MAP_FAILED)

errExit("mmap");

/* Код для работы с отображенным участком */

if (munmap(addr, length) == -1)

errExit("munmap");

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

Если в диапазоне адресов, заданных с помощью аргументов addr и length, не обнаруживается отображение, то вызов munmap() не выполняет никаких действий и просто возвращает 0 (сигнализируя об успехе).

Во время удаления отображения ядро уничтожает все блокировки памяти, удерживаемые процессом в заданном диапазоне адресов (эти блокировки устанавливаются с использованием вызовов mlock() или mlockall(); см. раздел 46.2).

Когда процесс завершается или выполняет вызов exec(), все его отображения удаляются автоматически.

Чтобы записать содержимое отображения обратно в исходный файл, перед удалением следует сделать вызов msync() (см. раздел 45.5).

45.4. Отображение файлов

Для отображения файла нужно выполнить следующие шаги.

1. Получить дескриптор файла (обычно с помощью вызова open()).

2. Передать этот файловый дескриптор вызову mmap() в виде аргумента fd.

В результате mmap() отобразит содержимое открытого файла на адресное пространство вызывающего процесса. После завершения вызова mmap() можно закрыть файловый дескриптор, не затрагивая отображения. Но в некоторых случаях его лучше оставить открытым (примеры приводятся в листинге 45.1 и в главе 50).

Перейти на страницу:

Похожие книги

1С: Бухгалтерия 8 с нуля
1С: Бухгалтерия 8 с нуля

Книга содержит полное описание приемов и методов работы с программой 1С:Бухгалтерия 8. Рассматривается автоматизация всех основных участков бухгалтерии: учет наличных и безналичных денежных средств, основных средств и НМА, прихода и расхода товарно-материальных ценностей, зарплаты, производства. Описано, как вводить исходные данные, заполнять справочники и каталоги, работать с первичными документами, проводить их по учету, формировать разнообразные отчеты, выводить данные на печать, настраивать программу и использовать ее сервисные функции. Каждый урок содержит подробное описание рассматриваемой темы с детальным разбором и иллюстрированием всех этапов.Для широкого круга пользователей.

Алексей Анатольевич Гладкий

Программирование, программы, базы данных / Программное обеспечение / Бухучет и аудит / Финансы и бизнес / Книги по IT / Словари и Энциклопедии
1С: Управление торговлей 8.2
1С: Управление торговлей 8.2

Современные торговые предприятия предлагают своим клиентам широчайший ассортимент товаров, который исчисляется тысячами и десятками тысяч наименований. Причем многие позиции могут реализовываться на разных условиях: предоплата, отсрочка платежи, скидка, наценка, объем партии, и т.д. Клиенты зачастую делятся на категории – VIP-клиент, обычный клиент, постоянный клиент, мелкооптовый клиент, и т.д. Товарные позиции могут комплектоваться и разукомплектовываться, многие товары подлежат обязательной сертификации и гигиеническим исследованиям, некондиционные позиции необходимо списывать, на складах периодически должна проводиться инвентаризация, каждая компания должна иметь свою маркетинговую политику и т.д., вообщем – современное торговое предприятие представляет живой организм, находящийся в постоянном движении.Очевидно, что вся эта кипучая деятельность требует автоматизации. Для решения этой задачи существуют специальные программные средства, и в этой книге мы познакомим вам с самым популярным продуктом, предназначенным для автоматизации деятельности торгового предприятия – «1С Управление торговлей», которое реализовано на новейшей технологической платформе версии 1С 8.2.

Алексей Анатольевич Гладкий

Финансы / Программирование, программы, базы данных