Книга: Программирование для Linux. Профессиональный подход
8.8. Семейство функций mlock(): блокирование физической памяти
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] Следовательно, каждую страницу необходимо проинициализировать:
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.1. Команда strace
- 8.2. Функция access(): проверка прав доступа к файлу
- 8.3. Функция fcntl(): блокировки и другие операции над файлами
- 8.4. Функции fsync() и fdatasync(): очистка дисковых буферов
- 8.5. Функции getrlimit() и setrlimit(): лимиты ресурсов
- 8.6. Функция getrusage(): статистика процессов
- 8.7, Функция gettimeofday(): системные часы
- 8.8. Семейство функций mlock(): блокирование физической памяти
- 8.9. Функция mprotect(): задание прав доступа к памяти
- 8.10. Функция nanosleep(): высокоточная пауза
- 8.11. Функция readlink(): чтение символических ссылок
- 8.12. Функция sendfile(): быстрая передача данных
- 8.13. Функция setitimer(): задание интервальных таймеров
- 8.14. Функция sysinfo(): получение системной статистики
- 8.15. Функция uname()
- 17.4.7. Блокирование нежелательных корреспондентов
- Мост между физической и логической структурой базы данных
- 3.2.1.2. Начальное выделение памяти: malloc()
- Неисправности оперативной памяти
- Как работает модуль оперативной памяти
- Описание типов модулей оперативной памяти
- Извлечение и установка модулей памяти
- Характеристики модулей памяти
- ПО для диагностики оперативной памяти
- Поиск и устранение неисправностей модулей памяти
- Пересмотр функций клиента
- Вызовы функций