Чтение онлайн

на главную - закладки

Жанры

Разработка приложений в среде 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: }

13.2.3. Отмена отображения областей

После окончания отображения в памяти процесс может отменить отображение памяти с помощью

munmap
. Это приводит к тому, что последующие доступы к этому адресу будут генерировать
SIGSEGV
(если только память не будет перераспределена) и сохраняет некоторые системные ресурсы. Отображение всех областей памяти отменяется, когда процесс заканчивает или начинает новую программу с помощью системного вызова
exec
.

#include <sys/mman.h>

int munmap(caddr_t addr, int length);

Параметр

addr
— это адрес
начала области памяти для отмены отображения, а
length
определяет, отображение какой части области памяти должно быть отменено. Обычно отображение каждой области отменяется отдельным вызовом
munmap
. Linux может фрагментировать карты, если отменено отображение только части области, но такой код будет непереносимым.

13.2.4. Синхронизация областей памяти на диск

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

msync
.

#include <sys/mman.h>

int msync(caddr_t addr, size_t length, int flags);

Первые два параметра,

addr
и
length
, устанавливают область для синхронизации с диском. Параметр
flags
устанавливает, каким образом должны синхронизироваться память и диск. Он состоит из одного или нескольких перечисленных ниже флагов, объединенных с помощью битового "ИЛИ".

MS_ASYNC
Модифицированные версии области памяти запланированы на "скорую" синхронизацию. Использовать можно только либо
MS_ASYNC
, либо
MS_SYNC
.
MS_SYNC
Модифицированные страницы в области памяти записываются на диск до возврата системного вызова
msync
. Использовать можно только либо
MS_ASYNC
, либо
MS_SYNC
.
MS_INVALIDATE
Эта опция позволяет ядру выяснять, записываются ли изменения на диск. Хотя эта опция не дает гарантию того, что они не будут записаны, она сообщает ядру, что необходимость сохранения изменений отсутствует. Этот флаг применяется только при особых условиях.
0
Передача
0
в
msync
работает в ядрах Linux, хотя она не очень хорошо документирована. Она похожа на
MS_ASYNC
, но означает, что страницы должны записываться на диск при любом удобном случае. Обычно это значит, что они будут сбрасываться на диск при каждом следующем запуске потока ядра
bdflush
(обычно он запускается каждые 30 секунд), в то время как
MS_ASYNC
записывает страницы более интенсивно.

13.2.5. Блокировка областей памяти

В Linux и многих других современных операционных системах для областей памяти можно организовать страничный обмен с диском (или отклонять, если их невозможно заменить каким-либо другим способом), когда возникает дефицит памяти. На приложения, чувствительные к ограничениям внешней синхронизации, может неблагоприятно повлиять задержка, к которой приводит подкачка страниц обратно в ОЗУ, когда это необходимо процессу. Для улучшения надежности таких приложений Linux позволяет процессу блокировать области памяти в ОЗУ, чтобы сделать эти синхронизации более предсказуемыми. В целях безопасности блокировка памяти разрешена только процессам с полномочиями привилегированного пользователя [87] . Если блокировать области памяти сможет любой процесс, то какой-то неисправный процесс может заблокировать все ОЗУ системы и привести ее к краху. Общее количество памяти, блокируемой процессом, не может превышать предел использования

RLIMIT_MEMLOCK
(см. главу 10).

87

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

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

Жалкая

Макинтайер Эмили
3. Долго и Несчастливо
Любовные романы:
современные любовные романы
5.00
рейтинг книги
Жалкая

Беглец

Бубела Олег Николаевич
1. Совсем не герой
Фантастика:
фэнтези
попаданцы
8.94
рейтинг книги
Беглец

Академия проклятий. Книги 1 - 7

Звездная Елена
Академия Проклятий
Фантастика:
фэнтези
8.98
рейтинг книги
Академия проклятий. Книги 1 - 7

Измена. Верни мне мою жизнь

Томченко Анна
Любовные романы:
современные любовные романы
5.00
рейтинг книги
Измена. Верни мне мою жизнь

Измена

Рей Полина
Любовные романы:
современные любовные романы
5.38
рейтинг книги
Измена

Гардемарин Ее Величества. Инкарнация

Уленгов Юрий
1. Гардемарин ее величества
Фантастика:
городское фэнтези
попаданцы
альтернативная история
аниме
фантастика: прочее
5.00
рейтинг книги
Гардемарин Ее Величества. Инкарнация

Сердце для стража

Каменистый Артем
5. Девятый
Фантастика:
фэнтези
боевая фантастика
9.20
рейтинг книги
Сердце для стража

Черный Маг Императора 11

Герда Александр
11. Черный маг императора
Фантастика:
юмористическое фэнтези
попаданцы
аниме
фэнтези
5.00
рейтинг книги
Черный Маг Императора 11

Имя нам Легион. Том 3

Дорничев Дмитрий
3. Меж двух миров
Фантастика:
боевая фантастика
рпг
аниме
5.00
рейтинг книги
Имя нам Легион. Том 3

Жена фаворита королевы. Посмешище двора

Семина Дия
Фантастика:
фэнтези
5.00
рейтинг книги
Жена фаворита королевы. Посмешище двора

Как я строил магическую империю 5

Зубов Константин
5. Как я строил магическую империю
Фантастика:
попаданцы
аниме
фантастика: прочее
фэнтези
5.00
рейтинг книги
Как я строил магическую империю 5

Блуждающие огни 2

Панченко Андрей Алексеевич
2. Блуждающие огни
Фантастика:
боевая фантастика
космическая фантастика
попаданцы
альтернативная история
фэнтези
5.00
рейтинг книги
Блуждающие огни 2

Ратник

Ланцов Михаил Алексеевич
3. Помещик
Фантастика:
альтернативная история
7.11
рейтинг книги
Ратник

Маленькая слабость Дракона Андреевича

Рам Янка
1. Танцы на углях
Любовные романы:
современные любовные романы
эро литература
5.25
рейтинг книги
Маленькая слабость Дракона Андреевича