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

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

Жанры

Программирование для Linux. Профессиональный подход

Самьюэл Алекс

Шрифт:

8.8. Семейство функций mlock: блокирование физической памяти

Функции семейства

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

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

после завершения программы.

Чтобы заблокировать область памяти, достаточно вызвать функцию

mlock
, передав ей указатель на начало области и значение длины области. ОС Linux разбивает память на страницы и соответственно блокирует ее постранично: любая страница, которую захватывает (хотя бы частично) заданная в функции
mlock
область памяти, окажется заблокированной. Определить размер системной страницы позволяет функция
getpagesize
. В Linux-системах, работающих на платформе x86, эта величина составляет 4 Кбайт.

Вот как можно выделить и заблокировать 32 Мбайт оперативной памяти:

const int alloc_size = 32 * 1024 * 1024;

char* memory = malloc(alloc_size);

mlock(memory, alloc_size);

Выделение страницы и блокирование ее с помощью функции

mlock
еще не означает, что эта страница будет предоставлена данному процессу, поскольку выделение памяти может происходить в режиме копирования при записи. [29] Следовательно, каждую страницу необходимо проинициализировать:

29

Режим копирования при записи означает, что Linux создает для процесса частную копию страницы только тогда, когда процесс записывает в нее какие-то данные.

size_t i;

size_t page_size = getpagesize;

for (i = 0; i < alloc_size; i += page_size)

 memory[i] = 0;

Процессу, осуществляющему запись на страницу, операционная система предоставит в монопольное использование ее уникальную копию.

Для разблокирования области памяти следует вызвать функцию

munlock
, передав ей те же аргументы, что и функции
mlock
.

Функция

mlockall
блокирует все адресное пространство программы и принимает единственный флаговый аргумент. Флаг
MCL_CURRENT
означает блокирование всей выделенной на данный момент памяти, но не той, что будет выделяться позднее. Флаг
MCL_FUTURE
задает блокирование всех страниц, выделенных после вызова функции
mlockall
. Сочетание флагов
MCL_CURRENT | MCL_FUTURE
позволяет блокировать всю память программы, как текущую, так и будущую.

Блокирование больших объемов памяти, особенно с помощью функции

mlockall
, несет потенциальную угрозу всей системе. Несправедливое распределение оперативной памяти приведет к катастрофическому снижению производительности системы, так как остальным процессам придется сражаться друг с другом за небольшой "клочок" памяти, вследствие чего они будут постоянно выгружаться на диск и загружаться обратно. Может даже возникнуть ситуация, когда оперативная память закончится и система начнет уничтожать процессы. По этой причине функции
mlock
и
mlockall
доступны лишь суперпользователю. Если какой-нибудь другой пользователь попытается вызвать одну из этих функций, она вернёт значение -1, а в переменную errno будет записан код
EPERM
.

Функция

munlосkall
разблокирует всю память текущего процесса.

Контролировать использование памяти удобнее всего с помощью команды

top
. В колонке
SIZE
ее выходных данных показывается размер виртуального адресного пространства каждой программы (общий размер сегментов кода, данных и стека с учетом выгруженных страниц). В колонке
RSS
приводится объем резидентной части программы. Сумма значений в столбце
RSS
не может превышать имеющийся объем ОЗУ, а суммарный показатель по столбцу
SIZE
не может быть больше 2 Гбайт (в 32-разрядных версиях Linux).

Функции семейства

mlock
объявлены в файле
<sys/mman.h>
.

8.9. Функция mprotect: задание прав доступа к памяти

В разделе 5.3, "Отображение файлов в памяти", рассказывалось о том, как осуществляется отображение файла в памяти. Вспомните, что третьим аргументом функции

mmap
является битовое объединение флагов доступа: флаги
PROT_READ
,
PROT_WRITE
и
PROT_EXEC
задают права чтения, записи и выполнения файла, а флаг
PROT_NONE
означает запрет доступа. Если программа пытается выполнить над отображаемым файлом недопустимую операцию, ей посылается сигнал
SIGSEGV
(нарушение сегментации), который приводит к завершению программы.

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

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

Корректное выделение памяти

Учтите, что память, выделяемая функцией

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

Кроме того, с помощью функции

mmap
можно обойти функцию
malloc
и запрашивать память непосредственно у ядра Linux.

Предположим, к примеру, что программа выделяет страницу, отображая в памяти файл

/dev/zero
. Память инициализируется как для чтения, так и для записи:

int fd = open("/dev/zero", O_RDONLY);

char* memory =

 mmap(NULL, page_size, PROT_READ | PROT_WRITE,

MAP_PRIVATE, fd, 0);

close(fd);

Далее программа запрещает запись в эту область памяти, вызывая функцию

mprotect
:

mprotect(memory, page_size, PROT_READ);

Существует оригинальная методика контроля памяти: можно защитить область памяти с помощью функций

mmap
и
mprotect
, а затем обрабатывать сигнал
SIGSEGV
, посылаемый при попытке доступа к этой памяти. Эта методика иллюстрируется в листинге 8.7.

Листинг 8.7. (mprotect.c) Обнаружение попыток доступа к памяти благодаря функции
mprotect

#include <fcntl.h>

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

Измена. Тайный наследник

Лаврова Алиса
1. Тайный наследник
Фантастика:
фэнтези
5.00
рейтинг книги
Измена. Тайный наследник

Инквизитор Тьмы

Шмаков Алексей Семенович
1. Инквизитор Тьмы
Фантастика:
попаданцы
альтернативная история
аниме
5.00
рейтинг книги
Инквизитор Тьмы

Наследник

Майерс Александр
3. Династия
Фантастика:
попаданцы
аниме
фэнтези
5.00
рейтинг книги
Наследник

Ротмистр Гордеев 3

Дашко Дмитрий
3. Ротмистр Гордеев
Фантастика:
попаданцы
альтернативная история
5.00
рейтинг книги
Ротмистр Гордеев 3

(Не)нужная жена дракона

Углицкая Алина
5. Хроники Драконьей империи
Любовные романы:
любовно-фантастические романы
6.89
рейтинг книги
(Не)нужная жена дракона

Идеальный мир для Лекаря 28

Сапфир Олег
28. Лекарь
Фантастика:
юмористическое фэнтези
аниме
фэнтези
5.00
рейтинг книги
Идеальный мир для Лекаря 28

Сыночек в награду. Подари мне любовь

Лесневская Вероника
1. Суровые отцы
Любовные романы:
современные любовные романы
5.00
рейтинг книги
Сыночек в награду. Подари мне любовь

Инквизитор Тьмы 2

Шмаков Алексей Семенович
2. Инквизитор Тьмы
Фантастика:
попаданцы
альтернативная история
аниме
5.00
рейтинг книги
Инквизитор Тьмы 2

Генерал Скала и ученица

Суббота Светлана
2. Генерал Скала и Лидия
Любовные романы:
любовно-фантастические романы
6.30
рейтинг книги
Генерал Скала и ученица

Искатель 1

Шиленко Сергей
1. Валинор
Фантастика:
фэнтези
попаданцы
рпг
5.00
рейтинг книги
Искатель 1

Сердце Дракона. Том 10

Клеванский Кирилл Сергеевич
10. Сердце дракона
Фантастика:
фэнтези
героическая фантастика
боевая фантастика
7.14
рейтинг книги
Сердце Дракона. Том 10

Печать мастера

Лисина Александра
6. Гибрид
Фантастика:
попаданцы
технофэнтези
аниме
фэнтези
6.00
рейтинг книги
Печать мастера

Выстрел на Большой Морской

Свечин Николай
4. Сыщик Его Величества
Детективы:
исторические детективы
полицейские детективы
8.64
рейтинг книги
Выстрел на Большой Морской

Кодекс Крови. Книга VII

Борзых М.
7. РОС: Кодекс Крови
Фантастика:
боевая фантастика
попаданцы
аниме
5.00
рейтинг книги
Кодекс Крови. Книга VII