13.2.2. Установка отображения в памяти
13.2.2. Установка отображения в памяти
Новые карты памяти создаются с помощью системного вызова mmap().
#include <sys/mman.h>
caddr_tmmap(caddr_t address, size_t length , int protection, int flags,
int fd, off_t offset);
Параметр address указывает, где именно в памяти необходимо отображать данные. Обычно address — это NULL, который означает, что для процесса не имеет значения местонахождение новой карты, и позволяет ядру выбрать любой адрес. Если адрес указан, он должен быть выровнен по страницам и в данный момент не использоваться. Если запрашиваемая карта будет конфликтовать с другой картой или не будет выровнена по страницам, mmap() может дать сбой.
Второй параметр, length, сообщает ядру, какую часть файлов следует отображать в памяти. Можно успешно отобразить больше памяти, чем количество данных в наличии у файла, но попытка доступа к нему может привести к SIGSEGV[86].
Процесс проверяет, какие типы доступа разрешены новой области памяти. Это должно быть одно или несколько значений из табл. 13.2, объединенных с помощью битового "ИЛИ", либо PROT_NONE, если доступ к отображаемой области запрещен. Файл может отображаться только для типов доступа, которые также были запрошены при изначальном открытии файла. Например, файл, открытый как O_RDONLY, не может быть отображен для записи с помощью PROT_WRITE.
Таблица 13.2. Флаги защиты mmap()
Флаг Описание PROT_READ Из отображаемой области можно читать. PROT_WRITE В отображаемую область можно записывать. PROT_EXEC Отображаемую область можно выполнять.Принудительное применение определенной защиты ограничено аппаратной платформой, на которой работает программа. Во многих архитектурах не разрешено выполнение кода в области памяти, если из нее запрещено чтение. При таком оборудовании отображение области с помощью PROT_EXEC эквивалентно ее отображению с помощью PROT_EXEC | PROT_READ.
По этой причине на флаги защиты памяти, передаваемые в mmap(), следует полагаться лишь как на обеспечивающие минимальную защиту.
В flags определяются другие атрибуты отображаемой области. В табл. 13.3 описаны все флаги. Многие флаги, поддерживаемые Linux, нестандартны, но могут быть полезны при особых условиях. В табл. 13.3 приведены различия между стандартными флагами mmap() и дополнительными флагами Linux. Во всех вызовах mmap() должен быть специфицирован MAP_PRIVATE или MAP_SHARED; остальные флаги устанавливать необязательно.
Таблица 13.3. Флаги mmap()
Флаг POSIX? Описание MAP_ANONYMOUS Да Игнорировать fd, создать анонимную карту. MAP_FIXED Да Сбой в случае недопустимого адреса (address). MAP_PRIVATE Да Запись приватна для процесса. MAP_SHARED Да Запись копируется в файл. MAP_DENYWRIТЕ Нет Не разрешать нормальную запись в файл. MAP_GROWSDOWN Нет Расширить область памяти сверху вниз. MAP_LOCKED Нет Блокировать страницы в памяти.MAP_ANONYMOUS Вместо отображения файла возвращается анонимное отображение. Оно ведет себя подобно обычному отображению, но без участия физического файла. Хотя эту область памяти нельзя ни использовать совместно с другими процессами, ни автоматически сохранять в файле, анонимное отображение позволяет процессам распределять новую память для индивидуального использования. Такое отображение часто применяется реализациями malloc(), а также еще несколькими специализированными приложениями. Параметр fd игнорируется при использовании этого флага. MAP_FIXED Если карту нельзя поместить по запрашиваемому адресу, mmap() завершается неудачей. Если этот флаг не определен, ядро попытается разместить карту по указанному адресу, но если это не удастся, то отобразит ее на альтернативный адрес. Если адрес, переданный в address, уже использовался mmap(), элемент, отображаемый в этой области, будет замещен новой картой памяти. Это означает, что лучше передавать только те адреса, которые были возвращены предыдущими вызовами в mmap(); если применяются произвольные адреса, может быть перезаписана область памяти, используемая системными библиотеками. MAP_PRIVATE Модификации области памяти должны быть индивидуальными для процесса. Их не следует совместно использовать с другими процессами, которые отображают этот же файл (процессами, отличающимися от связанных процессов, которые ответвляются после создания карты памяти), а также отражать в самом файле. Должен использоваться флаг MAP_SHARED или MAP_PRIVATE. Если область памяти незаписываемая, тип используемого флага не имеет значения. MAP_SHARED Изменения в области памяти копируются обратно в файл, который был отображен и использован совместно с другими процессами, отображающими этот же файл. (Для записи изменений в область памяти следует установить PROT_WRITE; иначе область памяти будет постоянной). Должен использоваться флаг MAP_SHARED или MAP_PRIVATE. MAP_DENYWRITE Обычно системные вызовы для нормального доступа к файлам (например, write()) могут модифицировать отображенный файл. Однако если область запускается, это будет не самым лучшим решением. Указание MAP_DENYWRITE приводит к тому, что операции записи файлов, отличные от тех, что совершаются через карту памяти, будут возвращать etxtbsy. MAP_GROWSDOWN Попытка немедленного доступа к памяти, расположенной непосредственно перед отображаемой областью, обычно вызывает SIGSEGV. Этот флаг заставляет ядро расширять область для младших адресов памяти по страницам, если процесс пытается получить доступ к памяти на младшей смежной странице, и продолжает процесс обычным образом. Это разрешает ядру автоматически расширять стеки процессов на платформах, на которых стеки расширяются сверху вниз (наиболее распространенный случай). Это специфичный для платформы флаг, применяемый обычно только для системного кода. Единственным ограничением для MAP_GROWSDOWN является ограничение размеров стека, рассматриваемое в главе 10. Если ограничение не установлено, ядро расширит отображенный сегмент, несмотря на то, выгодно ли это. Однако оно не будет расширять сегмент поверх остальных отображаемых областей. MAP_GROWSUP Этот флаг работает так же, как и MAP_GROWSDOWN, но предназначен для тех редких платформ, на которых стеки расширяются снизу вверх, что означает расширение области со старших, а не младших адресов. (В ядре версии 2.6.7 только архитектура parisc имеет стеки, расширяющиеся снизу вверх.) Как и MAP_GROWSDOWN, этот флаг зарезервирован для системного кода с установленным ограничением на размер стека. MAP_LOCKED Область блокируется в памяти. Это означает, что она никогда не будет подлежать страничному обмену. Это важно для систем реального времени (mlock(), рассматриваемый далее в этой главе, предоставляет еще один метод блокирования памяти). Обычно это может установить только привилегированный пользователь; обычным пользователям не разрешено блокировать страницы в памяти. Некоторые системы Linux допускают ограниченное распределение заблокированной памяти непривилегированными пользователями, и эта возможность, вероятно, вскоре будет добавлена к стандартному ядру Linux.
За флагами следует файловый дескриптор, fd, для файла, который предстоит отобразить в памяти. Если применялся флаг MAP_ANONYMOUS, его значение игнорируется. Последний параметр определяет, где именно в файле должно начаться отображение. Он должен быть целым числом, кратным размеру страницы. Большинство приложений начинают отображение с начала файла, указывая в качестве offset ноль.
Системный вызов mmap() возвращает адрес, который должен храниться в указателе. Если произошла ошибка, он возвращает адрес, эквивалентный -1. Для проверки этого необходимо привести тип константы -1 к caddr_t, а не к int. Это гарантирует, что результат будет верным независимо от размеров указателей и целых чисел.
Ниже приведена программа, действующая подобно команде cat и ожидающая отдельного имени в качестве аргумента командной строки. Она открывает этот файл, отображает его в памяти и записывает целый файл на стандартное устройство вывода одним вызовом write(). Полезно сравнить этот пример с простой реализацией cat из главы 11. Код примера также иллюстрирует, что карты памяти остаются на месте после закрытия отображаемого файла.
1: /* map-cat.с */
2:
3: #include <errno.h>
4: #include <fcntl.h>
5: #include <sys/mman.h>
6: #include <sys/stat.h>
7: #include <sys/types.h>
8: #include <stdio.h>
9: #include <unistd.h>
10:
11: int main(int argc, const char ** argv) {
12: int fd;
13: struct stat sb;
14: void * region;
15:
16: if ( fd = open(argv[1], O_RDONLY)) < 0) {
17: perror("open");
18: return 1;
19: }
20:
21: /* Вызвать fstat для файла, чтобы узнать, сколько необходимо памяти для его отображения */
22: if (fstat(fd, &sb)) {
23: perror("fstat");
24: return 1;
25: }
26:
27: /* можно было бы также отобразить как MAP_PRIVATE, поскольку
28: запись в эту память не планируется */
29: region = mmap(NULL, sb.st_size, PROT_READ, MAP_SHARED, fd, 0);
30: if (region == ((caddr_t) -1)) {
31: perror("mmap");
32: return 1;
33: }
34:
35: close(fd);
36:
37: if (write(1, region, sb.st_size) != sb.st_size) {
38: perror("write");
39: return 1;
40: }
41:
42: return 0;
43: }
Более 800 000 книг и аудиокниг! 📚
Получи 2 месяца Литрес Подписки в подарок и наслаждайся неограниченным чтением
ПОЛУЧИТЬ ПОДАРОКЧитайте также
Параметры отображения
Параметры отображения Еще одна группа атрибутов стиля управляет тем, как элемент будет отображаться на Web-странице, т. е. будет он блочным или встроенным, и будет ли он отображаться вообще. Эти атрибуты стиля применимы к любым элементам Web-страниц.Атрибут стиля visibility
Параметры отображения
Параметры отображения Еще одна группа атрибутов стиля управляет тем, как элемент будет отображаться на Web-странице, т. е. будет он блочным или встроенным, и будет ли он отображаться вообще. Эти атрибуты стиля применимы к любым элементам Web-страниц.Атрибут стиля visibility
6.5.2 Другие режимы отображения
6.5.2 Другие режимы отображения Помимо того, что может задаваться формат вывода на панель списка файлов, любую панель можно перевести в один из следующих режимов. • Режим "Информация". В этом режиме (рис. 6.3) на панель выводится информация о подсвеченном в другой панели файле
12.3 Способ отображения содержимого
12.3 Способ отображения содержимого Есть одна очень полезная функция, про которую некоторые пользователи, как показывает практика, даже не догадываются: изменение способа отображения содержимого папок. Попробуйте понажимать следующие сочетания кнопок, находясь в
Настройки отображения
Настройки отображения В силу того что на одной странице документа может быть большое количество текста, графики, иллюстраций, изначально InDesign отображает документ со слегка заниженным качеством – с уменьшенной детализацией графики и т. д.Для удобства пользования
Включение отображения
Включение отображения В этот момент обработчик событий Tick должен отобразить в панели toolStripStatusLabelClock текущее время, если значением по умолчанию члена-переменной DateTimeFormat является DateTimeFormat.ShowClock. Чтобы позволить пользователю переключаться между отображением даты и времени,
2.3. Установка типа памяти
2.3. Установка типа памяти Когда Вы создаете новую таблицу, Вы можете определять, который тип памяти использовать, добавляя опцию ENGINE к инструкции CREATE TABLE:CREATE TABLE t (i INT) ENGINE = INNODB;Если Вы опускаете опцию ENGINE или TYPE, используется заданный по умолчанию памяти. Обычно это MyISAM, но
Настройка стиля отображения
Настройка стиля отображения Стиль отображения можно выбрать в любой момент и при необходимости изменить его параметры или создать собственный стиль, изменяя настройки граней и кромок и используя затенение и фон. Команда VISUALSTYLES загружает Диспетчер визуальных стилей
Масштабирование отображения данных
Масштабирование отображения данных Данные, отображаемые в области просмотра окна данных, можно масштабировать – уменьшать или увеличивать диаграмму, что позволит более детально рассматривать шумы, помехи и сделает работу более удобной.В нижней части окна данных (см.
Контекст отображения (класс CDC)
Контекст отображения (класс CDC) Для отображения информации в окне или на любом другом устройстве приложение должно получить так называемый контекст отображения. Основные свойства контекста отображения определены в классе CDC. От него наследуется четыре различных класса,
Установка оперативной памяти
Установка оперативной памяти Как мы говорили в главе 4, неправильно вставить модуль оперативной памяти в предназначенный для этого слот, в общем-то, непросто. А не даст вам это сделать система ключей-выемок на модулях и слотах. Так что если модуль памяти не хочет входить в
3.2. Установка процессора и оперативной памяти
3.2. Установка процессора и оперативной памяти Сборка компьютера начинается с установки процессора и оперативной памяти, так как пока материнская плата не присоединена к корпусу, вы имеете свободный доступ к ее
Установка оперативной памяти
Установка оперативной памяти Установить модули оперативной памяти просто.Главное – правильно расположить модуль относительно слота (рис. 3.3). Рис. 3.3. Правильное расположение модуля относительно имеющихся ключейСделать это просто, так как и на планке памяти, и на слоте