Функции семейства mlock()
Блокирование физической памяти важно в программах реального времени, поскольку задержки, связанные с выгрузкой и подкачкой страниц, могут оказаться слишком длинными или возникать в самый неподходящий момент. Приложения, заботящиеся о безопасности своих данных, могут устанавливать запрет на выгрузку важных данных в файл подкачки, в котором они станут доступны злоумышленнику после завершения программы.
Чтобы заблокировать область памяти, достаточно вызвать функцию mlock()
mlock()
область памяти, окажется заблокированной. Определить размер системной страницы позволяет функция getpagesize()
. В Linux-системах, работающих на платформе x86, эта величина составляет 4 Кбайт.Вот как можно выделить и заблокировать 32 Мбайт оперативной памяти:
const int alloc_size = 32 * 1024 * 1024;
char* memory = malloc(alloc_size);
mlock(memory, alloc_size);
Выделение страницы и блокирование ее с помощью функции mlock()
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()
.8.9. Функция mprotect(): задание прав доступа к памяти
В разделе 5.3, "Отображение файлов в памяти", рассказывалось о том, как осуществляется отображение файла в памяти. Вспомните, что третьим аргументом функции mmap()
PROT_READ
, PROT_WRITE
и PROT_EXEC
задают права чтения, записи и выполнения файла, а флаг PROT_NONE
означает запрет доступа. Если программа пытается выполнить над отображаемым файлом недопустимую операцию, ей посылается сигнал SIGSEGV
(нарушение сегментации), который приводит к завершению программы.