Читаем 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); /* Получаем размер страницы в системе */

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

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

C++ Primer Plus
C++ Primer Plus

C++ Primer Plus is a carefully crafted, complete tutorial on one of the most significant and widely used programming languages today. An accessible and easy-to-use self-study guide, this book is appropriate for both serious students of programming as well as developers already proficient in other languages.The sixth edition of C++ Primer Plus has been updated and expanded to cover the latest developments in C++, including a detailed look at the new C++11 standard.Author and educator Stephen Prata has created an introduction to C++ that is instructive, clear, and insightful. Fundamental programming concepts are explained along with details of the C++ language. Many short, practical examples illustrate just one or two concepts at a time, encouraging readers to master new topics by immediately putting them to use.Review questions and programming exercises at the end of each chapter help readers zero in on the most critical information and digest the most difficult concepts.In C++ Primer Plus, you'll find depth, breadth, and a variety of teaching techniques and tools to enhance your learning:• A new detailed chapter on the changes and additional capabilities introduced in the C++11 standard• Complete, integrated discussion of both basic C language and additional C++ features• Clear guidance about when and why to use a feature• Hands-on learning with concise and simple examples that develop your understanding a concept or two at a time• Hundreds of practical sample programs• Review questions and programming exercises at the end of each chapter to test your understanding• Coverage of generic C++ gives you the greatest possible flexibility• Teaches the ISO standard, including discussions of templates, the Standard Template Library, the string class, exceptions, RTTI, and namespaces

Стивен Прата

Программирование, программы, базы данных
1С: Бухгалтерия 8 с нуля
1С: Бухгалтерия 8 с нуля

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

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

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

В этом полном руководстве по C# 4.0 - языку программирования, разработанному специально для среды .NET, - детально рассмотрены все основные средства языка: типы данных, операторы, управляющие операторы, классы, интерфейсы, методы, делегаты, индексаторы, события, указатели, обобщения, коллекции, основные библиотеки классов, средства многопоточного программирования и директивы препроцессора. Подробно описаны новые возможности C#, в том числе PLINQ, библиотека TPL, динамический тип данных, а также именованные и необязательные аргументы. Это справочное пособие снабжено массой полезных советов авторитетного автора и сотнями примеров программ с комментариями, благодаря которым они становятся понятными любому читателю независимо от уровня его подготовки. Книга рассчитана на широкий круг читателей, интересующихся программированием на C#.Введите сюда краткую аннотацию

Герберт Шилдт

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