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

В целом флаг MAP_FIXED не следует применять в портируемых приложениях; вместо этого лучше передать аргументу addr значение NULL, позволяя системе автоматически выбрать адрес для размещения отображения.

Но существует ситуация, в которой портируемое приложение могло бы воспользоваться флагом MAP_FIXED. Речь идет о случае, когда при вызове mmap() участок памяти длиной length, начинающийся с адреса addr, перекрывает собой страницы предыдущего отображения и заменяет их. Можно отобразить несколько участков файла (или файлов) на один непрерывный участок памяти. Для этого нужно сделать следующее.

1. Использовать mmap() для создания анонимного отображения (см. раздел 45.7). В данном вызове аргументу addr передается значение NULL, а флаг MAP_FIXED опускается. Это позволяет ядру выбрать адрес для отображения.

2. Задействовать несколько вызовов mmap() с флагом MAP_FIXED, чтобы отобразить (то есть наложить) участки файла на разные участки отображения, созданного в предыдущем шаге.

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

Начиная с Linux 2.6 того же эффекта можно достичь, используя системный вызов remap_file_pages(), который будет описан в следующем разделе. Однако применение флага MAP_FIXED является более портируемым, так как вызов remap_file_pages() доступен только в Linux.

45.11. Нелинейные отображения: remap_file_pages()

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

Один из способов создания нелинейного отображения описан в предыдущем разделе и заключается в использовании нескольких вызовов mmap() с флагом MAP_FIXED. Однако такой подход не очень хорошо масштабируется. Проблема в том, что каждый вызов mmap() создает в области виртуальной памяти ядра (англ. virtual memory area, VMA) структуру данных. И каждый раз область VMA тратит время на подготовку и потребляет некий объем памяти ядра, не предназначенной для сбрасывания на диск. Кроме того, наличие большого количества таких областей может ухудшить производительность диспетчера виртуальной памяти; в частности, есть вероятность существенного увеличения времени обработки отказа страницы (с этой проблемой сталкивались некоторые большие системы управления базами данных, хранящие в одном файле несколько разных отображений).

Каждая строка в файле /proc/PID/maps представляет одну область VMA.

Начиная с версии 2.6, ядро Linux поддерживает системный вызов remap_file_pages() для создания нелинейных отображений, который не приводит к появлению множества областей VMA. Он используется следующим образом.

1. Делается вызов mmap() для создания отображения.

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

3. Вызов remap_file_pages() дает возможность отобразить одну и ту же страницу файла на разные сегменты отображенного участка памяти.

#define _GNU_SOURCE

#include

int remap_file_pages(void *addr, size_t size, int prot, size_t pgoff,

int flags);

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

Аргументы pgoff и size обозначают участок файла, который нужно переместить в памяти. Первый из них указывает на начальную позицию участка файла в единицах, равных размеру страницы памяти (возвращаемый вызовом sysconf(_SC_PAGESIZE)). Аргумент size определяет длину участка в байтах. Значение addr служит двум целям:

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

• указывает на адрес в памяти, по которому находятся страницы файла, заданные с использованием аргументов pgoff и size.

Аргументы addr и size должны быть кратными размеру страницы памяти в системе. В противном случае они округляются до ближайшего кратного.

Представьте, что мы применяем следующий вызов mmap() для отображения трех страниц открытого файла, на который ссылается дескриптор fd, и в итоге аргументу addr присваивается адрес 0x4001a000:

ps = sysconf(_SC_PAGESIZE); /* Получаем размер страницы в системе */

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

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

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

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

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

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

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

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

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